在ES6中,定义Promise对象是一个构造函数,我们实际运用Promise时,用来生成Promise实例,这个Promise函数有三个状态pending(进行中)、fulfilled(已成功)和rejected(已失败),两个参数:resolved(已成功)和rejected(已失败),这两个参数它们是函数,是由JavaScript引擎提供。这两个状态改变都需要经过pending,并且状态一经改变,不会再变。
Promise实例的then方法,可以分别指定resolved状态和rejected状态的回调函数;
let promise=new Promise(function(resolved,rejected){
resolved("resolved:success");
rejected(new Error("rejected:fail"));
console.log("promise");
});
promise.then(function(value){
console.log(value);
},function(error){
console.log(error);
});
console.log("END");
输出结果:
这里可以看到,Promise新建后立即执行,并且状态已经转变为resolved后,再回调rejected抛出错误是无效,也就是状态改变了,就不会再改变。then方法是回调函数,因此在当前的同步任务执行完以后再执行。
catch 方法,发生错误时的回调函数;
let promise=new Promise(function(resolved,rejected){
rejected(new Error("fail!"));//也可以写成 throw new Error("fail!");
});
promise.then(function(value){
console.log(value);
}).catch(function(err){
console.log(err);
});
输出结果:
状态为resolved时,调用then()方法,输出“success!”,状态为rejected时,调用catch()方法,输出“fail!”;
可能你会问,then方法里不是也可以回调rejected吗?
因为catch方法无论前面有几个promise对象,他们之中任何一个抛出错误,都会被catch捕获,即catch可以捕获then方法执行中的错误。因此then方法的第二个参数是可选的或者不使用的。
finally方法,不管promise最后状态是如何,都会执行的操作。finally方法的回调函数不接受任何参数,也与promise状态无关。
let promise=new Promise(function(resolved,rejected){
rejected(new Error("fail!"));
});
promise.then(function(value){
console.log(value);
}).catch(function(err){
console.log(err);
}).finally(function(){
console.log("finally!");
});
输出结果:
Promise.all()方法,用于将多个promise实例,包装成一个新的Promise实例;
let p1=new Promise(function(resolved,rejected){
throw new Error("p1 error!");
})
.then(value=>value)
.catch(err=>{console.log(err);return err;});
let p2=new Promise(function(resolved,rejected){
resolved("success!");
})
.then(value=>value)
.catch(err=>{console.log(err);return err;});
let p3=new Promise(function(resolved,rejected){
resolved("success!");
})
.then(value=>value)
.catch(err=>{console.log(err);return err;});
Promise.all([p1,p2,p3])
.then(value=>console.log(value))
.catch(err=>console.log("all:"+err));
输出结果:
all()方法,只有全部的Promise实例状态是resolved 的情况下才是resolved,不然就是rejected状态。
上面的p1是rejected,但是它有自己的catch方法,所以返回的是新的一个promise的实例,p1指向的实际上是这个实例,这个实例执行完catch方法后,也会变成resolved,因此上面代码的all方法参数里的三个实例都是resolved,就调用了then方法。
如果p1没有自己的catch方法,则p1就是返回rejected,那就会调用promise.all()方法的catch方法,如下:
let p1=new Promise(function(resolved,rejected){
throw new Error("p1 error!");
})
.then(value=>value);
let p2=new Promise(function(resolved,rejected){
resolved("success!");
})
.then(value=>value)
.catch(err=>{console.log(err);return err;});
let p3=new Promise(function(resolved,rejected){
resolved("success!");
})
.then(value=>value)
.catch(err=>{console.log(err);return err;});
Promise.all([p2,p1,p3])
.then(value=>console.log(value))
.catch(err=>console.log("all:"+err));
输入结果:
点击进入:利用Promise实现的红绿灯效果例子