promise 对象
概念
- 定义:
- promise 是一种异步编程解决方案
- promise是一个容器,内部保存着在未来才会结束的事件(异步操作)的结果
- 特点
- promise 对象的状态不受外界影响,只有异步操作的结果,可以知道此刻处于何种状态(pending、fulfilled、rejected)
- promise 对象的状态一旦改变,就不会再次变化(pending->fulfilled、pending->rejected),当状态改变完成,在对 promise 对象添加回调函数,依然返回原先的结果
- promise 对象可以将异步操作流程以同步操作流程表达出来,避免了层层嵌套
- promise 对象无法取消,一旦创建就立即执行
- 若不设置回调函数,promise 对象内部抛出的错误,不会反映到外部
- 当处于 pending 状态时,无法得知目前进展到何种阶段
- 当某些事件不断的反复发生,使用 stream 模式比部署 promise 更好
基本用法
- new Promise():创建 promise 实例 🌰,
- 其中第一个函数参数中,resolve 函数是将 promise 状态从 pending->resolved,并将异步操作的结果(函数参数),作为参数传递出去;reject 函数效果类似
- promise 实例新建后,回调函数会立即执行(是同步的),只用 then 等链式调用是异步的
- resolve 函数参数可以是另一个 promise 实例
- promise 实例的参数回调函数中的 resolve 函数会在回调函数内部所有的同步操作执行完再执行,为了避免发生意外,可使用对 resolve 使用 return 操作,防止后面代码被执行
- promise 内部的错误捕获传递到外部,即不会影响到外部代码的正常执行
- Promise.prototype.then(resolvedFn, rejectedFn)
- 两个参数都是回调函数,都是可选的
- then 方法返回的是一个新的 promise 实例(不是原来的),故而可用于链式操作
- Promise.prototype.catch(errFn)🍏
- 当 catch 前面的异步操作链条中某环节抛出错误,就会执行该方法
- catch 方法返回一个 promise 实例,故而可用于链式操作
- 等同于 Promise.prototype.then(null/undefined, errFn),一般不使用这方法,因为 then 内部的方法也可以被 catch 捕获
- 若 promise 状态已经变为 resolved,再次抛出错误是无效的,比如在构造函数的回调函数中
resolve(); throw new Error()
,这是无效的
- Promise.prototype.finally(callback)
- 用于指定不管 promise 对象的状态最终如何,都会执行的操作
- 其中回调函数 callback 不接受任何参数,即无法知道前面的 promise 的状态如何,所以回调函数内部的代码应该是与状态无关的,不依赖于 promise 的执行结果
- Promise.all(promiseArray)
- 将多个 promise 实例,包装成一个新的 promise 实例
- 其中参数可以不是数组,但必须要具备一个迭代器接口,且返回的每个成员都是 promise 实例
- 实例的状态由参数中的所有实例决定,只有全部为 resolved,才为 resolved,此时所有实例的返回值组成数组传递给后续链;若有一个是 rejected,则变为 rejected,第一个 rejected 的返回值传递给后续链
- 若参数的某些实例具备 catch 方法,则这些实例发生错误不会调用 all 方法链条的 catch 方法
- Promise.race(promiseArray)
- 将多个 promise 实例,包装成一个新的 promise 实例
- 只有参数的一个实例状态率先改变,它也跟着改变状态,最先改变状态的返回值,将传递给后续链
- Promise.allSettled(promiseArray)
- 将多个 promise 实例,包装成一个新的 promise 实例
- 只有所有的实例都返回结果(fulfilled/rejected),包装实例才会结束,且状态总是 fulfilled
- 用途:不关系操作的结果,只关心异步操作是否结束
- Promise.any(promiseArray)
- 将多个 promise 实例,包装成一个新的 promise 实例
- 若有一个参数实例状态变为 fulfilled,则包装实例状态变为 fulfilled,当所有参数实例状态变为 rejected 时,包装实例状态才会变为 rejected
- any 抛出的错误,是一个 AggregateError 实例,相当于一个数组,每个成员对应于一个 rejected 抛出的错误
- Promise.resolve()
- 将现有对象转为 promise 对象,等价于
new Promise(resolve => resolve('foo'))
- 参数分为以下情况:
- 参数是 promise 实例,则该函数将原封不动返回这个实例
- 参数是 thenable 对象(具有 then 方法的对象),会将这个对象转为 promise 对象,并执行 thenable 对象中的 then 方法
- 参数是无 then 方法的对象/不是一个对象,返回一个 promise 实例,状态为 resolved
- 无参,返回一个 resolved 的 promise 实例
- 注意立即 resolved 的实例,是在本轮事件循环结束后执行,而非下轮循环开始时
- 将现有对象转为 promise 对象,等价于
- Promise.reject()
- 返回要给新的 promise 实例,实例的状态为 rejected,等价于
new Promise(reject => reject('出错了'))
- 该方法的参数会原封不动的作为后续链的参数
- 返回要给新的 promise 实例,实例的状态为 rejected,等价于
- Promise.try()
- 一个提案,不想区分函数是同步还是异步的,但都想用 promise 来处理他们,并使用 promise 的 API
javascript
// 🌰:new Promise()创建promise实例
const promise = new Promise(function (resolve, reject) {
// some code...
if (/* 异步操作成功操作 */) {
resolve(value)
// other sync code,此处的代码优于resolve函数执行
} else {
reject(error)
}
})
// 🍏:catch
const promise = new Promise(fucntion (resolve, reject) {
throw new Error('test')
})
promise.catch(function (err) {
console.log(err)
})
// 等同于
const promise = new Promise(function (resolve, reject) {
try {
throw new Error('test')
} catch (e) {
reject(e)
}
})
promise.catch(fucntion (err) {
console.log(err)
})
// 等同于
const promise = new Promise(function (resolve, reject) {
reject(new Error('test'))
})
promise.catch(function (err) {
console.log(err)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
应用
- 图片加载:当图片加载完成时,状态变为 fulfilled
- promise 与 generator 结合使用:使用 generator 管理流程时,遇到异步操作,返回一个 promise