前言:必要前提
阅读本文有一个很重要的前提—— 就是知道 Promise
是怎么构造的,也可以说知道在构造Promise实例过程中究竟发生了什么,是理解Promise必不可缺的关键一步。
试着问下自己这几个问题:
- Promise的接收的回调函数是怎么执行的?(MDN称之为
executor
) resolve
和reject
是什么? 是谁提供的?- 返回的
Promise
是怎么确定状态的?
如果回答这些问题没有把握,可以参考:
- MDN Promise
- Promise简介
- 其他博文:尽可能是 github上的,分析得头头是道、有理有据,但有些难理解就是了。
如果上面的问题都能很好的回答上来,那么就正式开始用Promise/A+
规范解读Promise
(虽说如此,还是要结合MDN 和 tutorialpoint上的内容)。
开始吧。
预备:Promise基本构造(非规范)
注意:
- 这不是
Promise/A+
的一部分,但是知道它对于理解Promise
规范的细节很有帮助。 - 下面的内容我会在括号中引用,或是在伪代码中引用。
任何一个Promise
都会有两个最关键的部分:
[[PromiseStatus]]
: 表明操作执行后的状态。默认为pending
; 在Firefox
浏览器中,该字段为state
[[PromiseValue]]
:是保存在Promise
中的结果,它可能是一个reason
(拒绝原因,异常.etc); 或是一个value
(成功操作后提供的结果)。
关于[[PromiseStatus]]
和[[PromiseValue]]
的设置:
- 在调用
resolve
函数时,如果提供了参数y
; 那么[[PromiseValue]]
则被设为y
的值。此时[[PromiseStatus]]
将切换为fulfilled
(或resolved
) ; 例如:resolve(y)
- 在调用
reject
函数时,如果提供了异常或一个值r
, 那么[[PromiseValue]]
将被设为r
。它可能是一个异常(Exception)。此时[[PromiseStatus]]
将切换为rejected
。 例如:reject(r)
或throw r
一旦[[PromiseStatus]]
被设为fulfilled
或rejected
二者任何一个状态,都可以说该Promise被settled。
总结如下:
任何一个Promise
实例pr
的value
或reason
都能表示为:
pr . [[PromiseValue]] // 它可能是value ,也可能是 reason。
任何一个Promise
实例pr
的状态都能表示为:
pr . [[PromiseStatus]] // pending / fulfilled / rejected 三者之一。
Promise 与 then方法
注意:
- 参考来源: Promise/A+规范
- 虽然是参考规范,但是并非是规范的翻译,小生也没有翻译规范的能力;下文大多是阅读规范后的理解。
Promise/A+
规范规定,Promise
必须为以下三种状态之一:
pending
: 操作还未确定结果。此时promise
状态(即[[PromiseStatus]]
)可以切换到fulfilled
或rejected
fulfilled
:操作已经成功完成。无法再切换到其他状态。此时必须有一个确定的value
(即[[PromiseValue]]无法再更改)rejected
:操作已经失败。无法再切换到其他状态。此时必须有一个确定的reason
(即[[PromiseValue]]无法再更改)
任何一个promise
实例都必须有一个then
方法;同样的,任何具有then
方法的对象都可以称之为thenable
对象。
如下所示:
promise.then(onFulfilled, onRejected)
onFulfilled
与onRejected
都是可选的,但是它们如果不是函数,都会被忽略。注意它们只能在promise被settled后调用并且只能被调用一次。onFulfilled
是一个函数时,promise
的状态为fulfilled
时被调用。并将promise
的value
(即[[PromiseValue]]
)作为onFulfilled
的第一个参数。onRejected
是一个函数时,promise
的状态为rejected
状态时被调用,并且promise
的reason
(也是[[PromiseValue]]
) 作为它的第一个参数。
注意:
- 只有在当前任务(即宏任务)完成后才能调用
onFulfilled
与