什么是 Promise
Promise
是异步编程的一种解决方案。所谓 promise
,从语法上看是一个对象,里面保存着未来某个时刻才会结束的事件的结果。promise
对象有以下两个特点:
- 对象的状态不受外界影响。
promise
对象代表一个异步操作,有三种状态:pending
(进行中)、fulfilled(已成功)
和rejected(已失败)
。 只有异步操作的结果才可以决定当前具体是哪种状态,任何其他操作都无法改变这个状态。这也是被称为promise
的原因。 - 状态一旦改变,就会凝固,任何时候都可以得到这个结果。
promise
对象的状态改变只有两种可能:- 从
pending
变成fulfilled
- 从
pending
变成rejected
- 从
一旦以上任意一种情况发生了,状态就会凝固了,不会再改变,会一直保持这个结果,这时就称为 resolved
(已定型)。为了表达方便,本文中的 resolved
统一指 fulfilled
状态。
Promise
是一个构造函数,用来生成promise
实例。
const promise = new Promise(function(resolve,reject){
//一般是发送异步请求
if(/*异步操作成功*/){
resolve();
}else{//异步操作失败
reject();
}
});
从上面看,Promise
构造函数接受一个函数作为参数,该函数有两个参数分别是 resolve
和 reject
。它们是两个函数,由解释引擎提供,不需要自己部署。
resolve
函数的作用是,将 promise
对象的状态从 “未完成” 变为 “成功” (从 pending
变为 fulfilled
),在异步操作成功时调用,并将异步操作的结果作为参数传递出去。
rejected
函数的作用是,将 promise
对象的状态从 “未完成” 变为 “失败” (从 pending
变为 rejected
),在异步操作失败时调用,并将异步操作抛出的错误作为参数传递出去。
实例方法
一、Promise.prototype.then(func,func)
除了上面的这种方式来处理异步结果以外,还可以通过实例方法 then
来实现一样的效果:
let promise = new Promise()
promise.then(function(value){
//success
},function(error){
//failure
})
then
方法接收两个回调函数作为参数,第一个回调是 promise
对象的状态变为 resolved
时调用,第二个回调函数是 promise
对象的状态变为 rejected
时调用。其中,第二个参数是可选的。
then
方法返回的是一个新的 promise
实例,因此,可以采用链式调用。
二、Promise.prototype.catch(func)
该方法用于指定发生错误时的回调函数。然而,你可能会有疑问上面的 then
方法也能够处理出错的情况,那 catch
是干啥的呢?
是的,Promise.prototype.catch()
是 .then(null,rejection)
的别名!
如果将成功和失败的操作都堆在一个方法中太臃肿了,所以将不同的情况分开来处理。
let promise = new Promise()
promise.then(function(response){
//success
}).catch(function(error){
//error
})
上面代码中,如果异步操作成功,则执行 then
方法指定的回调;否则执行 catch
方法回调。另外,如果在 then
运行中抛出了异常,同样会被 catch
方法捕获。promise
对象的错误具有 “冒泡” 的性质,如果错误没有被处理,则会被一致向后传递,直到被捕获为止。
catch
方法返回的是 promise
对象,所以还是可以进行链式调用,甚至是继续 .then
。
三、Promise.prototype.finally(func)
该方法用于指定不管 promise
对象最后状态如何,都会执行的操作。
promise
.then(result => {})
.catch(error => {})
.finally(() => {})
静态方法
一、Promise.resolve()
【用途】
该方法用于将对象转换为 Promise
实例。
【参数说明】
该方法的参数比较复杂,有四种情况:
- 如果参数是一个
Promise
实例,那么直接返回 - 如果参数是一个具有
then
方法的对象,那么会将该对象转换为Promise
实例的同时立即执行then
方法 - 如果参数不是具有
then
方法或者不是对象,则返回一个新的promise
对象,状态为resolved
- 空参,直接返回一个
resolved
状态的对象。
二、Promise.reject()
【用途】
用于返回一个新的 promise
实例,实例的状态为 rejected
。
【参数说明】
该方法的参数会作为 reject
的理由,变成后续方法的参数。
三、Promise.any()
【用途】
用于将多个 promise
实例包装成一个新的 promise
实例。
【参数说明】接受一个数组作为参数,数组的元素是 promise
实例。如果有一个实例变成 fulfilled
状态,那么这个新的实例也就会变成 fulfilled
;如果所有实例都变成 rejected
状态,那么这个新的实例就会变成 rejected
。
四、Promise.race()
【用途】
用于将多个 promise
实例包装成一个新的 promise
实例。
【参数说明】
与上面的方法相似,都是接收一个数组作为参数,数组的元素都是 promise
实例。不同的是,在多个 promise
实例中,哪个先改变状态,就将哪个的结果赋值给新的实例。
五、Promise.all()
【用途】
用于将多个 promise
实例包装为一个新的 promsie
实例。
【参数说明】
参数是一个具有 Iterator
接口并且返回的每个成员都是 promise
实例。
该实例的状态由多个实例决定,只有全部实例状态都变成 fulfilled
时,新的实例才会变成 fulfilled
;或者只有全部实例状态都变成 reject
时,新的实例状态才会变成 rejected
。
只有满足以上任意一种情况,才能触发新的实例的回调函数。