Promise 详解
一、前言
Promise
意在让异步请求逻辑代码变得干净、直观、井然有序。
Promise
在设计上具有原子性,即只有三种状态:等待(Pending
)、成功(Fulfilled
)、失败(Rejected
)。在调用支持Promise
的异步方法时,逻辑变得非常简单,在大规模的软件工程开发中具有良好的健壮性。
二、基本语法
要想给一个函数赋予Promise
能力,就要先创建一个Promise
对象,并将其作为函数值返回。Promise
对象要求传入一个函数,并带有resolve
和reject
参数。这是两个用于结束Promise
等待的函数,对应的状态分别是成功和失败。
function asyncMethod(...args){
return new Promise((resolve,reject)=>{
//...
})
}
将新创建的Promise
对象作为异步方法的返回值,所有的状态就可以使用它所提供的方法进行控制了。
三、异步操作
创建 Promise
对象后,就可以进行异步操作,并通过resolve (value)
和reject (reason)
方法来控制Promise
的原子状态。
-
resolve(value)
方法控制的是当前Promise
对象是否进入成功状态,一旦执行该方法并传入有且只有一个返回值,Promise
便会从等待状态(Pending
)进入成功状态(Fulfilled
),Promise
也不会再接收任何状态的变。 -
reject (reason)
方法控制的是当前Promise
对象是否进入失败阶段,与resolve
方法相冋,一旦进入失败阶段就无法再改变。
new Promise((resolve,reject)=>{
api.call('fetch-data',(err,data)=>{
if(err) return reject(err)
resolve(data)
})
})
其中,在Promise
的首层函数作用域中一旦出现throw
语句,Promise
对象便会直接进入失败状态,并以throw
语句的抛出值作为错误值进行错误处理。
(new Promise(function() {
throw new Error ('test')
)))
.catch(err =>console.error(err))
但是,return
语句并不会使Promise
对象进入成功状态,而会使Promise
停留在等待状态。所以在Promise
对象的执行器(executor
)内需要谨慎使用return
语句来控制代码流程。
四、处理 Promise 状态
与resolve(value)
和reject(reason)
方法对应,Promise
对象有两个用于处理Promise
对象状态变化的方法。
这两个方法都会返回一个Promise
对象,Promise
对象的组合便会成为一个Promise
对象链,呈流水线的模式作业。
asyncMethod()
.then((...args)=>args /*...*/)
.catch(err=>console.error(err))
Promise
链式处理默认被实现,即.then(onFulfilled)
或.catch(onRejected)
会处理在onFulfilled
和onRejected
中所返回或抛出的值。
-
如果
onFulfilled
或onRejected
中所返回的值是一个Promise
对象,则该Promise
对象会被加入到Promise
的处理链中。 -
如果
onFulfilled
或onRejected
中返回的值并不是一个Promise对象
,则会返回一个己经进入成功状态的Promise
对象。 -
如果
onFulfilled
或onRejected
中因为throw
语句而抛出一个错误err,则会返回一个已经进入失败状态的Promise
对象。
之所以说Promise
对象链呈流水线的模式进行作业,是因为在Promise
对象对自身的onFulfilled
和onRejected
响应器的处理中,会对其中返回的Promise
对象进行处理。
其内部会将这个新的Promise
对象加入到Promise
对象链中,并将其暴露出来,使其继续接受新的Promise
对象的加入。只有当Promise
对象链中的上一个Promise
对象进入成功或失败阶段,下一个Promise
对象才会被激活,这就形成了流水线的作业模式。
Promise
对象链还有一个十分实用的特性–Promise对象状态具有传递性。
如果Promise
对象链中的某一环出现错误,Promise
对象链便会从出错的环节开始,不断向下传递,直到出现任何一环的Promise
对象对错误进行响应为止。
五、高阶方法
5.1 Promise.all(iterable)
该方法可以传入一个可迭代对象(如数组),并返回一个Promise
对象,该Promise
对象会在当可迭代对象中的所有Promise
对象都进入完成状态(包括成功和失畋)后被激活。
-
如果可迭代对象中的所有
Promise
对象都进入了成功状态,那么该方法返回的Promise
对象也会进入成功状态,并以一个可迭代对象来承载其中的所有返回值。 -
如果可迭代对象中的所有
Promise
对象存在一个进入了失败状态,那么该方法返回的Promise
对象也会进入失败状态,并以那个进入失败状态的错误信息作为自己的错误信息。
Promise.all(promises)
.then(values=>{
//...
})
.catch(err=>console.error(err))
5.2 Promise.race(iterable)
Promise .race (iterable)
方法同样也接受一个包含若干个Promise
对象的可迭代对象,但不同的是这个方法会监听所有的Promise
对象,并等待其中的第一个进入完成状态的Promise
对象,一旦有第一个Promise
对象进入了完成状态,该方法返回的Promise
对象便会根据这第一个完成的Promise
对象的状态而改变。
Promise.race(promises)
.then(values=>{
//...
})
.catch(err=>console.error(err))
注意⚠️,其他方法仍然会继续执行。
六、拓展阅读
- 点赞
- 收藏
- 关注作者
评论(0)