Noted:
Javscript 是一种单线程直译式的脚本语言,所有的代码都是单线程。由于它具备非阻塞式的特性,导致许多读写、网络等操作都需要回调函数。
//Snippet 1,
Post.getTen(null, page, function (err, posts, total) {
if (err) {
posts = [];
}
....
});
//Snippet 2,
Post.getTen = function(name, page, callback) {
//打开数据库
mongodb.open(function (err, db) {
if (err) {
return callback(err);
}
//读取 posts 集合
db.collection('posts', function (err, collection) {
var docs = [];
var total = 10;
callback(null, docs, total);
});
});
};
为了解决上面代码显示的问题,在ES6中做了一个统一规范Promise,从而优雅的回避了大量的回调函数。
可以在通过以下代码查看local的浏览器是否支持Promise的特性
'use strict';
new Promise(function () {alert('Support Promise!')});
Promise 实例,
//Snippet 1,
function test(resolve, reject) {
var timeOut = Math.random() * 2;
setTimeout(function () {
if (timeOut < 1) {
resolve('200 OK');
}
else {
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
}
//Snippet 2,
var p1 = new Promise(test);
var p2 = p1.then(function (result) {
console.log('successd ' + result);
});
var p3 = p2.catch(function (reason) {
console.log('failed ' + reason);
});
//Snippet 3,
new Promise(test).then(function (result) {
console.log('successd ' + result);
}).catch(function (reason) {
console.log('failed ' + reason);
});
Snippet 2 显示,
变量p1是一个Promise对象,它负责执行test函数。由于test函数在内部是异步执行的,当test函数执行成功时,我们告诉Promise对象。
当test函数执行失败时,我们告诉Promise对象。
Snippet 3 显示,
Promise对象可以串联起来,可见Promise 最大的好处就是在代码的执行过程中把执行的代码与处理结果的代码严格的分开了。
Promise 执行串行异步任务
要执行串行的异步任务任务,我们并不需要在写嵌套函数,只需要按照下面的格式:
job1.then(job2).then(job3).then(job4).catch(function (err) { console.log(err)});
// 0.5秒后返回input*input的计算结果:
function multiply(input) {
return new Promise(function (resolve, reject) {
console.log('multiply ' +input+ ' * ' +input);
setTimeout(resolve, 500, input * input);
});
}
// 0.8秒后返回input*input的计算结果:
function add(input) {
return new Promise(function (resolve, reject) {
console.log('add ' +input+ ' + ' +input);
setTimeout(resolve, 800, input + input);
});
}
var p = new Promise(function (resolve, reject) {
console.log('start new Promise ... ');
resolve(2)
});
p.then(multiply)
.then(add)
.then(multiply)
.then(add)
.then(function (result){
console.log('Got value ' + result)
}).catch(function (err) {
console.log(err);
});
Promise 执行并行任务
Promise 也可以执行并行的任务,当我们的支付宝页面一方面要显示账户的余额,另外也要显示打折商家的信息。
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'balance');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 800, 'Detail Mes');
});
Promise.all([p1, p2]).then(function (results) {
console.log(results)
}).catch(function (err) {
console.log(err);
});
Promise 执行竞争任务
Promise 也可以实现多任务之间的竞争,比如抢红包。
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'balance');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 800, 'Detail Mes');
});
Promise.race([p1, p2]).then(function (results) {
console.log(results)
}).catch(function (err) {
console.log(err);
});