【Promise】Promises/A+中文翻译

引言

俗话说好记性不如烂笔头,因此我决定翻译一下Promise/A+规范,帮助本身更加深入的理解promise,为以后手撸promise源码作准备,同时也但愿本篇文章对你们也有所帮助。前端

正文

这是一个实现者为实施者提供的开源的、可互操做的JavaScript Promise规范git

promise表明一个异步操做的最终结果。与promise的主要互动方式是经过then方法注册回调函数来接收promise的最终值或者promise未完成的缘由。github

该规范详细描述了then方法的行为,它提供了一个可互操做的基础,全部Promises/A + 符合 promise的实现均可以依赖于这个基础。所以,该规范被认为是很是稳定的。尽管Promises/A+的做者可能偶尔会修改规范,对其进行一些向后兼容的小修改,以解决新发现的问题,咱们只有在仔细考虑、讨论和测试后,才会集成大型或者不向后兼容的变动。web

历史上,Promises/A+澄清了早期的Promises/A proposal的行为条款,将其拓展到涵盖事实的行为,而且省略了未指定或有问题的部分。算法

最后,Promises/A+规范的核心不是处理如何建立、完成或者失败的promises,而是选择专一于一个可互操做的then方法。将来在配套规范中的工做可能会涉及这些主题。promise

1.术语

  • 1.1 promise是具备then方法的对象或者函数,其行为符合规范。app

  • 1.2 thenable是定义在then方法上的对象或者函数。异步

  • 1.3 value 是任何合法的JavaScript值(包括undefinedthenable,或者promise函数

  • 1.4 exception是使用抛出语句抛出的值学习

  • 1.5 reason是一个代表promise为何失败的值

2.需求

2.1 Promise状态

  • 2.1.1 当promise状态为pending时:

    • 2.1.1.1 能够变为完成状态或者失败的状态
  • 2.1.2 当promise状态为fulfilled时:

    • 2.1.2.1 不能变为任何一种状态

    • 2.1.2.2 必须有一个value,这个value不能改变

  • 2.1.3 当promiserejected时:

    • 2.1.3.1 不能变为任何一种状态

    • 2.1.3.2 必须有一个reason,这个reason不能改变

2.2 then方法

promise必须提供一个then方法,来访问它当前或最终的valuereason

一个promisethen方法接收两个参数:

promise.then(onFulfilled, onRejected)
复制代码
  • 2.2.1 onFulfilledonRejected都是可选的参数

    • 2.2.1.1 若是onFulfilled不是函数,必须被忽略

    • 2.2.1.2 若是onRejected 不是函数,必须被忽略

  • 2.2.2 若是onFulfilled是一个函数

    • 2.2.2.1 它必须在promise完成后被调用,而后把promise的值做为它的第一个参数

    • 2.2.2.2 它不能在promise完成前被调用。

    • 2.2.2.3 它不能被调用超过一次。

  • 2.2.3 若是onRejected是一个函数

    • 2.2.3.1 它必须在promise失败后被调用,而后把promise的值做为它的第一个参数

    • 2.2.3.2 它不能在promise失败前被调用。

    • 2.2.3.3 它不能被调用超过一次。

  • 2.2.4 在执行上下文堆栈(execution context)仅包含平台代码以前,不得调用 onFulfilledonRejected[3.1]

  • 2.2.5 onFulfilledonRejected必须做为函数调用(即没有this值)[3.2]

  • 2.2.6 then方法可能在同一次promise中被调用屡次

    • 2.2.6.1 若是/当promise完成时,全部相应的onFulfilled回调必须按照最原始的then顺序来执行

    • 2.2.6.2 若是/当promise失败时,全部相应的onRejected回调必须按照最原始的then顺序来执行

  • 2.2.7 then方法必须返回一个promise
    promise2 = promise1.then(onFulfilled, onRejected);

    • 2.2.7.1 若是onFulfilledonRejected返回一个值x,请运行Promise Resolution Procedure [[Resolve]](promise2, x)

    • 2.2.7.2 若是onFulfilledonRejected抛出一个异常epromise2必须拒绝并将e做为reason

    • 2.2.7.3 若是onFulfilled不是一个函数,且promise1为完成状态,promise2必须使用与promise1相同的value完成

    • 2.2.7.4 若是onRejected不是一个函数,且promise1为失败状态,promise2必须使用与promise1相同的reason完成

2.3 Promise解决程序

promise解析过程是一个以输入promisevalue的抽象操做,咱们记做[[Resolve]](promise, x),若是xthenable,假设x的行为有点像promise,它会尝试让promise采用x的状态。不然,它将使用x值来完成promise

只要有实现Promises/A+兼容的then方法,对thenable的处理容许使用promise实现可以互操做。它还容许Promises/A+实现使用合理的then方法“同化”不一致的实现。

运行[[Resolve]](promise, x),执行如下的步骤:

  • 2.3.1 若是promisex引用同一个对象,则用TypeError做为reason拒绝promise

  • 2.3.2 若是x是一个promise,则采用它的状态[3.4]

    • 2.3.2.1 若是xpending状态,promise必须保持pending状态直到x成功或者失败

    • 2.3.2.2 若是x为完成状态,用相同的值完成promise

    • 2.3.2.3 若是x为失败状态,用相同的reason拒绝promise

  • 2.3.3 若是x是一个对象或函数

    • 2.3.3.1 让thenx.then[3.5]

    • 2.3.3.2 若是检索属性x.then的结果抛出一个异常e,用e做为reason拒绝promise

    • 2.3.3.3 若是then是一个函数,把x做为this调用它,第一个参数resolvePromise 和第二个参数rejectPromise,其中:

      • 2.3.3.3.1 若是resolvePromisey值调用,运行[[Resolve]](promise, y)

      • 2.3.3.3.2 若是rejectPromise被为rreason调用,用r来拒绝promise

      • 2.3.3.3.3 若是 resolvePromiserejectPromise都被调用,或者对同一个参数进行屡次调用,则第一次调用优先,任何进一步的调用被忽略

    • 2.3.3.4 若是then不是函数,用x来完成promise

  • 2.3.4 若是x不是对象或者函数,用x来完成promise

若是使用参与循环的可循环链的可转换组件解决了一个promise,这样,[[Resolve]](promise, thenable)的递归性质致使了再次调用[[Resolve]](promise, thenable),遵循上述算法将致使无限递归。鼓励(但不是必须)实现来检测这种递归且用包含信息的TypeError做为reason拒绝promise。[3.6]

3.笔记

3.1

这里的“平台代码”是指引擎,环境和promise实现代码。在实践中,这个需求确保onFulfilledonRejected异步执行,在事件循环以后调用then,而且使用一个新栈。这能够经过setTimeout或者setImmediate宏任务机制,或者使用MutationObserver或者process.nextTick微任务机制来实现。因为promise实现被视为平台代码,所以它自己可能包含一个任务调度队列或“蹦床”在其中调用处理程序。

3.2

也就是说,在严格模式下,thisundefined,在宽松模式中,它是一个全局对象(global object)

3.3

在知足全部需求的状况下,能够容许实现promise2 === promise1,每一个实现都应该记录它是否可以产生promise2 === promise1以及在何种条件下产生

3.4

一般,只有x来自于当前实例时,才知道它是一个真正的promise,此条款容许使用特定的实现方法来采用已知符合promise的状态。

3.5

这个过程首先存储对x.then的引用,而后测试,而后调用这个引用。避免了对x.then属性的屡次访问。这些预防措施对于确保访问者属性的一致性很是重要,由于访问者属性的值可能在两次检索之间发生变化。

3.6

实现不该该对thenable链的深度设置任何限制,并假设递归超出限制。只有真正的循环才会致使TypeError,若是遇到无穷多个thenable链,那么永远递归是正确的行为。

总结

熟悉promise规范有助于咱们深入理解promise原理,为以后看源码,手写源码铺路~好久不碰英语了,很长时间以后第一次作翻译,若是有翻译很差的地方,还但愿指出~咱们共同窗习,共同进步~

最后,分享一下个人公众号「web前端日记」,若是想更加及时的看见文章,立刻就去关注哇😍

相关文章
相关标签/搜索