什么叫promise?
Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码;让代码更加的直观。就是当执行完一次异步操作后,会有一次回调,不管成功还是失败,成功就对应成功的回调,失败就对应失败的回调。
那我们为什么要使用promise?
比如我们在工作中经常会碰到这么一个需求,比如我使用ajax发一个A请求后,成功后拿到数据,我们需要把数据传给B请求;如果直接在ajax的回调中再嵌套另外一个ajax,代码不是很直观,因此,我们可以使用Promise解决这个问题。
Promise基本使用
一般我们new一个Promise对象,当然可以是作为result返回给一个方法或者赋值给一个变量,然后通过then获取Promise执行结果,成功(resolve)或者是失败(reject),这里有一个必须清楚:Promise对象一旦创建立即执行。因此,我们可以把promise对象定义在一个function里面,然后把该promise对象在该function返回。所以一般来说Promise具有以下三个状态:
has-resolution-Fulfilled
:resolve被调用之后,调用onFulfiled(也就是then的处理成功参数)has-rejection
:reject被调用之后,调用Rejected的(也即是then的处理error函数)unresolve
:Pending,待定,就是Promise刚刚创建的时候。
function runAsync2() {
let p = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('执行完成2');
resolve('成功2');
//reject('失败2');
}, 2000);
})
return p;
}
runAsync2().then((data) => {
console.log(data);
})
.catch((data) => {
console.log(data);
})
由于在异步操作中调用了resolve,就会调用then的处理成功函数,我们可以把then函数理解成处理成功的回调函数,虽然实际上并不是这样的意思。同理,如果在回调函数中调用了reject,就是调用catch的回调函数。如果在then回调函数中出错了,也会调用catch。
还有一点需要注意的:Promise的状态一单改变,将不可修改,比如已经调用了resolve()状态,那么再去调用reject或者是resolve已经没有作用了
链式操作的用法
promise还可以对多个then进行连用,也就是可以理解成是我们需要嵌套使用ajax。它比传递callback函数要简单、灵活的多。
例子:
let a=2;
function runAsync1(){
let p = new Promise(function (resolve,reject){
setTimeout(() => {
resolve('成功1');
}, 2000);
})
return p;
}
function runAsync2() {
let p = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('执行完成2');
resolve('成功2');
//reject('失败2');
}, 2000);
})
return p;
}
function runAsync3() {
let p = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('执行完成3');
resolve('成功3');
}, 2000);
})
return p;
}
runAsync1().then((data) => {
console.log(data);
return runAsync2();
}).then((data) =>{
console.log(data);
return runAsync3();
})
.then((data) => {
console.log(data);
})
.catch((data) => {
console.log(data);
})
all的用法
Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。我们仍旧使用上面定义好的runAsync1、runAsync2、runAsync3这三个函数,看下面的例子:
let a=2;
function runAsync1(){
let p = new Promise(function (resolve,reject){
setTimeout(() => {
resolve('成功1');
}, 2000);
})
return p;
}
function runAsync2() {
let p = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('执行完成2');
resolve('成功2');
//reject('失败2');
}, 2000);
})
return p;
}
function runAsync3() {
let p = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('执行完成3');
resolve('成功3');
}, 2000);
})
return p;
}
runAsync1().then((data) => {
console.log(data);
return runAsync2();
}).then((data) =>{
console.log(data);
return runAsync3();
})
.then((data) => {
console.log(data);
})
.catch((data) => {
console.log(data);
})
race的用法
all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思。race的用法与all一样,我们把上面runAsync1的延时改为1秒来看一下:
Promise
.race([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
console.log(results);
});
这三个异步操作同样是并行执行的。结果你应该可以猜到,1秒后runAsync1已经执行完了,此时then里面的就执行了,然后依次执行1、2、3的。
参考文献:http://www.cnblogs.com/lvdabao/p/es6-promise-1.html
https://liweijieok.github.io/2018/03/21/%E5%89%8D%E7%AB%AF/promise_learn/