前言
promise是一个构造函数,自己身上有resolve、reject、all、race等方法,在其原型链上有then、catch方法, resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected,then里面的函数就跟我们平时的回调函数一个意思,拿到resolve的参数,能够在异步任务执行完成之后被执行。
举个例子:
function runAsync(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('执行完成');
resolve('随便什么数据');
}, 2000);
});
return p;
}
runAsync().then(function(data){
console.log(data);
});
等价于
function runAsync(callback){
setTimeout(function(){
console.log('执行完成');
callback('随便什么数据');
}, 2000);
}
runAsync(function(data){
console.log(data);
});
在JavaScript的世界中,所有的代码都是单线程执行的
异步函数可以采用回调函数来实现
更加优雅的方式是利用promise,进行链式调用,函数只需要关心其中的逻辑,并不需要关心如何处理其中的结果。
古人云,“一诺千金”,这种“承诺将来会执行”的对象叫做promise
如何使用
举个简单的例子
new Promise(test).then(function (result) {
console.log('成功:' + result);
}).catch(function (reason) {
console.log('失败:' + reason);
});
我们生成了一个promise对象,想让它执行test函数,如果执行成功那么会调用then(注册了成功的回调函数),如果失败则调用catch(注册了失败的回调函数)
实现原理
此为廖雪峰老师的一张图,很容易能够看出其中的原理,需要注意的是里面所需要的执行的函数都是异步的
扩展使用
- 串行执行若干任务(链式操作)
- 如果需要多个回调函数层层回调,callback hell
- 如果不使用promise则需要一层一层嵌套地写代码,难懂又不方便调试
采用promise可以链式调用
job1.then(job2).then(job3).catch(handleError);
其中job1、2、3都是promise对象,当然也可以不用在上级函数中return promise对象,而只是return一个普通的数据
runAsync1()
.then(function(data){
console.log(data);
return runAsync2();
})
.then(function(data){
console.log(data);
return '直接返回数据'; //这里直接返回数据
})
.then(function(data){
console.log(data);
});
那么在最后一个then中的function将会直接获取到数据,根据相应函数进行处理、输出。(其实跟我们不传入promise是一样的)。
2. 并行执行若干任务
- 全部都完成后执行then
我们可以采用promise.all()
来实现。 - 取先完成的返回结果即可
使用promise.race()
即可
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1'
});
参考资料:
ES6 Promise 用法讲解
廖雪峰的官方网站