Promise 的构造函数接收一个参数,参数也是一个函数,这个函数有两个入参,分别是resolve 和 reject,
resolve 和 reject 都是Promise内部封装的函数,参数类型可以任意,但是都只支持一个参数,可以用数组或者json等完成多参数传递
特别注意:Promise 与主线程之间是异步的
先看下面这种完整的写法:
下面代码模拟了一个业务场景:当a ==10 时表示成功,非10表示失败,可以用a=10 和a=11 分别执行
var promise = new Promise(function(resolve, reject) {
var a=11;
if(a== 10){
resolve("成功");
}else{
reject("失败");
}
});
promise.then(function(value) {
console.log("resolve 会触发 then 执行 :"+value);
}).catch(function(value){
console.log("reject 会触发 catch 执行:"+value);
});
console.log("这句话会先打印,说明 Promise 与主线程之间是异步的")
一般都会简写,省略其中的function ,用 => 代替, 简写如下:
var promise = new Promise( (resolve, reject) => {
var a=11;
if(a== 10){
resolve("成功");
}else{
reject("失败");
}
});
promise.then( (value) => {
console.log("resolve 会触发 then 执行 :"+value);
}).catch( (value) => {
console.log("reject 会触发 catch 执行:"+value);
});
console.log("这句话会先打印,说明 Promise 与主线程之间是异步的")
Promise 有什么用?
避免异步回调层层嵌套的,比如要先调用A接口,成功后再调用B,B成功后再调用C,那么伪代码如下:
$.ajax(A接口,data,function(xx){
A的回调处理
调用B接口
$.ajax(B接口,data,function(yy){
B的回调处理
调用C接口
$.ajax(C接口,data,function(zz){
C的回调处理
})
})
})
这样的嵌套较深,一般会认为可读性不好(个人觉得也要看业务场景,不复杂的业务也还好,而且可以将A、B、C的回调处理逻辑写成独立的方法进行调用),用Promise 可以将这个结构改造一下,但是代码量会稍微增多:
function callA() {
return new Promise( (resolve, reject) => {
$.ajax(A接口,data,function(xx){
A的回调处理
resolve(xx);
})
});
}
function callB() {
return new Promise( (resolve, reject) => {
$.ajax(B接口,data,function(yy){
B的回调处理
resolve(yy);
})
});
}
function callC() {
return new Promise( (resolve, reject) => {
$.ajax(C接口,data,function(zz){
C的回调处理
resolve(zz);
})
});
}
callA().then( (xx) => {
A的回调处理
return callB();
}).then( (yy) => {
B的回调处理
return callC();
}).then( (data) => {
C的回调处理
});
使用 Promise 将层层的嵌套回调做成了链式调用,至于是否真正方便,还是看使用场景
以上是Promise 的常用用法,还有 all和race 批量执行的用法,可以了解下,知道有这么个东西:
all 用法:
Promise.all([callA(), callB(), callC()])
.then(function(data){
console.log(data);// 打印出 [A的返回值,B的返回值,C的返回值]
});
all 接收一个 Promise 数组,会同时执行数组中的每个方法(注意是同时执行,不是顺序执行),当所有方法执行完成,将每个方法的返回值按顺序封装成一个数组,然后统一执行then方法。
这里会打印出 [A的返回值,B的返回值,C的返回值]
适合A的值不用作为B或C的入参等一些情况(适合A、B、C之间没有先后顺序的依赖)
与java中的CyclicBarrier类似
race用法:
all是所有方法完成才执行then, race 是其中任意一个方法执行完了就执行then,切记:then只执行一次
Promise.race([callA(), callB(), callC()])
.then(function(data){
console.log(data);// 仅打印出 第一个执行完毕的方法的返回值
});
虽然then只触发一次,但是callA(), callB(), callC() 还是都会各自执行完成的