Promis是异步编程的一种解决方案,比传统的解决方案一一回调函数和事件—更加合理和强大。所谓的Promise,简单来说就是一个容器,里面保存这某个未来才会结束的事件(通常是异步操作)的结果。从语法上说,Promise是 一个对象,从它可以获取异步操作的消息。
Promise对象代表一个异步操作,有三种状态:pedding(进行中)、fulfilled(已成功)、rejected(已失败)。Promise对象的状态改变只有两种可能:从pedding变为fulfilled和从pedding变为rejected。只要这两种情况发生,状态就凝固了,不会再改变。
Promise构造函数接受一个函数作为参数,该函数有两个 参数分别是resolve和reject。他们是两个函数。resovle函数的作用是将Promise对象的状态从pedding变为fulfilled,即从未完成变为成功。在异步操作成功时调用,并将一步操作结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从未完成变为失败,在异步操作失败时调用,并将异步操作作为参数传递出去。
let promise = new Promise((resolve,reject)=>{
//成功时调用
resolve('成功!')
//失败时调用
reject("失败")
})
then方法可以接受两个回调作为参数。第一个回调是Promise对象的状态变为resolve时调用,第二个回调是Promise对象的状态变为rejected时调用。
function timeout(ms){
return new Promise((resolve,reject)=>{
setTimeout(resolve,ms,'success')
//setTimeout(reject,ms,'failed')
})
}
timeout(100).then((value)=>{
console.log(value) //success
},(failedReason)=>{
console.log(failedReason) //failed
})
catch方法是.then(null,rejection)或.then(undefined,rejection)的别名,用于指定发生错误时的回调函数。
finally()方法用于指定不管Promise对象最后状态如何,都会执行的操作。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
上面代码中,不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
Promise.all()方法多用于多个Promise实例,包装成一个新的Promise实例。
let p = Promise.all([p1,p2,p3]);
上面代码中,Promise.all()方法接受一个数组作为参数,p1、p2、p3都是Promise实例,如果不是,就会先调用Promise.resolve方法,将参数转换为Promise实例。
p的状态由p1、p2、p3决定,分成两种情况。
1、只有p1、p2、p3的状态都变成fulfilled,p的状态才会变为fulfilled,此时p1、p2、p3的返回值组成一个数组,传递个p的回调函数。
2、只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被rejected的实例的返回值,会传递个p的回调函数。
// 生成一个Promise对象的数组
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
return getJSON('/post/' + id + ".json");
});
Promise.all(promises).then(function (posts) {
// ...
}).catch(function(reason){
// ...
});
Promise.race()方法同样是将多个Promise实例,包装成一个新的Promise实例。
let p = Promise.race([p1,p2,p3])
上面代码中,只要p1、p2、p3之中,有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的promise实例返回的值,就传递个p的回调函数。
•Promise的状态一经改变就不能再改变。
•.then和.catch都会返回一个新的Promise。
•catch不管被连接到哪里,都能捕获上层未捕捉过的错误。
•在Promise中,返回任意一个非 promise 的值都会被包裹成 promise 对象,例如return 2会被包装•为return Promise.resolve(2)。
•Promise 的 .then 或者 .catch 可以被调用多次, 但如果Promise内部的状态一经改变,并且有了一个值,那么后续每次调用.then或者.catch的时候都会直接拿到该值。
•.then 或者 .catch 中 return 一个 error 对象并不会抛出错误,所以不会被后续的 .catch 捕获。
•.then 或 .catch 返回的值不能是 promise 本身,否则会造成死循环。
•.then 或者 .catch 的参数期望是函数,传入非函数则会发生值透传。
•.then方法是能接收两个参数的,第一个是处理成功的函数,第二个是处理失败的函数,再某些时候你可以认为catch是.then第二个参数的简便写法。
•.finally方法也是返回一个Promise,他在Promise结束的时候,无论结果为resolved还是rejected,都会执行里面的回调函数。