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 状态
方法 | 方法内容 |
---|---|
promise.then(onFulfilled[, onRejected]) | 处理 Promise 对象的成功状态并接收返回值,也可以处理失败状态并处理失败的原因(可选) |
promise.catch(onRejected) | 处理 Promise 对象的失败状态并处理失败的原因 |
这两个方法都会返回一个 Promise 对象,Promise 对象的组合便会成为一个 Promise 对象链,呈流水线(Pipeline)的模式作业。
asyncMethod()
.then((..args) => args /* ... */ )
.catch(err => console.error(err));
Promise 链式处理默认被实现,即 .then(onFulfilled) 或 .catch(onRejected) 会处理在 onFulfilled 和 onRejected 中返回或抛出的值。
- 如果 onFulfilled 或 onRejected 中所返回的值是一个 Promise 对象,则该 Promise 对象会被加入到 Promise 的处理链中。
- 如果 onFulfilled 或 onReject 中所返回的值并不是一个 Promise 对象,则会返回一个已经进入成功状态的 Promise 对象。
- 如果 onFulfilled 或 onRejected 中因为 throw 语句而抛出一个错误 err,则会返回一个已经进入失败状态的 Promise 对象。
Prmoise 对象的状态具有传递性
如果 Promise 对象链中的某一环出现错误,Promise 对象链便会从出错的环节开始,不断向下传递,直到出现任何一环的 Promise 对象对错误进行响应为止。
高级使用方法
all方法
promise.all(iterable
)
该方法传入一个可迭代对象(如数组),并返回一个 Promise 对象,该 Prmise 对象会在当可迭代对象中的所有 Promise 对象都进入完成状态(包括成功和失败)后被激活。
- 如果可迭代对象中的所有 Promise 对象都进入了成功状态,那么该方法返回的 Promise 对象也会进入成功状态,并以一个可迭代对象来承载其中一个的所有返回值。
- 如果可迭代对象中 Promise 对象的其中一个进入了失败状态,那么该方法返回的 Promise 对象也会进入失败状态,并以那个进入失败状态的错误信息作为自己的错误信息。
const promise = [async(1), async(2), async(3), async(4)];
Promise.all(promises)
.then(values => {
// ...
})
.catch(err => console.error(err));
race方法
promise.race(iterable)
这个方法会监听所有的 Promise 对象,并等待其中的第一个进入完成状态的 Promise 对象。一旦有第一个 Promise 对象进入了完成状态,该方法返回的 Promise 对象便会根据这第一个完成的 Promsie 对象的状态而改变。
const promise = [async(1), async(2), async(3), async(4)];
Promise.race(promises)
.then(values => {
// ...
})
.catch(err => console.error(err));