promise/A+规范翻译以及手写实现

2019-03-20 admin
  • 要求 2.1 promise 状态

    一个promise必须是三种状态其中的一种状态:pending,fulfilled 或者 rejected。

    2.1.1 当promise处于pending状态时:

       2.1.1.1 可以转变到 fulfilled 或者 rejected 状态。
    

    2.1.2 当promise处于fulfilled状态时:

       2.1.2.1 一定不能够转变到其他任何一种状态。
       2.1.2.2 必须有一个value,并且这个值一定不能改变。
    

    2.1.3 当promise处于rejected状态时:

       2.1.3.1 一定不能够转变到其他任何一种状态。
       2.1.3.2 必须有一个reason,并且这个值不能够改变。
    
    

    在这里,“一定不能改变”意味着不可变的身份(即===),但并不意味着深层不变性。(个人理解为是value/reason指向的地址是不可变的,但假若value/reason为一个对象,则对象内的值是可变的。)

    2.2 then 方法 一个promise必须提供一个then方法去访问当前或者最终的value或者reason。 一个promise的then方法接受两个参数:

    promise.then(onFulfilled, onRejected)
    

    2.2.1 onFulfilled 和 onRejected 都是可选的参数:

        2.2.1.1 如果 onFulfilled  不是一个函数,它必须被忽略。
        2.2.1.2 如果 onRejected 不是一个函数,它必须被忽略。
    

    2.2.2 如果 onFulfilled 是一个函数:

       2.2.2.1 promise 是 fulfilled 状态时它必须被调用,并且 promise 的 value 作为它的第一个参数。
       2.2.2.2 它一定不能在 promise 进入 fulfilled 状态之前被调用。
       2.2.2.3 它一定不能够调用超过一次。
    

    2.2.3 如果 onRejected 时一个函数:

       2.2.3.1 promise 是 rejected 状态时它必须被调用,并且 promise 的 reason 作为它的第一个参数。
       2.2.3.2 它一定不能在 promise 进入 rejected 状态之前被调用。
       2.2.3.3 它一定不能够调用超过一次。
    

    2.2.4 直到执行上下文堆栈仅包含平台代码之前,onFulfilled 或 onRejected 不能够被调用。[3.1] 2.2.5 onFulfilled 和 onRejected 必须以函数的形式被调用(即没有this值)。[3.2] 2.2.6 then 可以在同一个promise被调用多次:

       2.2.6.1 当 promise 处于 fulfilled 状态时,各个 onFulfilled 回调必须按其原始调用的顺序执行。
       2.2.6.2 当 promise 处于 rejected 状态时,各个 onRejected 回调必须按其原始调用的顺序执行。
    

    2.2.7 then 必须返回一个promise [3.3]:

     promise2 = promise1.then(onFulfilled, onRejected);
    
       2.2.7.1 如果 onFulfilled 或 onRejected 返回一个值 x,运行Promise解决程序 [[Resolve]](promise2, x)。
       2.2.7.2 如果 onFulfilled 或 onRejected 抛出一个意外 e,promise2 必须以 e 为 reason 被 rejected。
       2.2.7.3 如果 onFulfilled 不是一个函数并且 promise1 处于 fulfilled 状态,promise2 必须以与 promise1 同样的 value
               转变到 fulfilled 状态。
       2.2.7.4 如果 onRejected 不是一个函数并且  promise1 处于 rejected状态,promise2 必须以与 promise1 同样的 reason
               转变到 rejected状态。
    
    

    2.3 Promise解决程序

    promise解决程序是一个抽象的操作,它把一个 promise 和一个 value 作为输入,我们将这个表示为 [[Resolve]](promise, x)。如果 x 是一个 thenable ,它将会试图让 promise 采用 x 的状态,前提是x的行为至少有点像一个 promise。否则,它将会用值 x 执行 promise。 对这些 thenable 的处理使得与 promise 实现方式能够去互相操作。只要它们公开了符合 Promise/A+ 的 then 方法。它还使得 promises/A+ 实现方式能够采用合理的 then 方法去“同化”不一致的实现方式。 为了运行[[Resolve]](promise, x),执行以下步骤: 2.3.1 如果 promise 与 x 是同一个对象,以 Tyeperror 作为 reason 去 reject promise。 2.3.2 如果 x 是一个 promise,使用它的状态:

       2.3.2.1 如果 x 处于 pending 状态,promise 必须保持 pending 状态直到 x 处于 fulfilled 或者 rejected 状态。
       2.3.2.2 如果 x 处于 fulfilled 状态,以相同的 value 去 fulfill promise。
       2.3.2.3 如果 x 处于 rejected 状态,以相同的 reason 去 reject promise。
    

    2.3.3 否则,如果 x 是一个对象或者函数:

       2.3.3.1 让 then 作为 x.then。
       2.3.3.2 如果取属性 x.then 会导致抛出异常 e,则以 e 为 reason reject promise。
       2.3.3.3 如果 then 是一个函数,让 x 作为 this 调用它,第一个参数为 resolvePromise,第二个参数为 rejectPromise,然后:
           2.3.3.3.1 如果使用value y 调用 resolvepromise 时,运行[[Resolve]](promise, y)。
           2.3.3.3.2 如果使用reason r 调用 rejectPromise 时,也用 r reject promise。
           2.3.3.3.3 如果 resolvePromise 和 rejectPromise 都被调用了,或多次调用同一参数,那么第一个调用优先,其他的调用都会被忽略。
           2.3.3.3.4 如果调用 then 的过程中抛出了一个意外 e,
               2.3.3.3.4.1 如果 resolvePromise 或者 rejectPromise 被调用了,那么忽略它。
               2.3.3.3.4.2 否则,把 e 作为 reason reject promise。
       2.3.3.4 如果 then 不是一个函数,将 x 作为参数执行 promise。
    

    2.3.4 如果 x 不是一个对象或者函数,将 x 作为参数执行 promise。

    如果一个参与了 thenable 循环链的 thenable 去 resolve promise,这样 [[Resolve]](promise, thenable) 的递归性质最终会导致 [[Resolve]](promise, thenable) 会被再次调用,遵循上述算法将会导致无限递归。我们鼓励去实现(但不是必需的)检测这样的递归,并以 TypeError 作为 reason 去 reject Promise。[3.6]

[转载]原文链接:https://segmentfault.com/a/1190000018589798

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-58255.html

文章标题:promise/A+规范翻译以及手写实现

相关文章
2015年JavaScript或“亲库而远框架”
2014年过去了,作为一个JavaScript开发者很难满怀信心的去“挽回”一个特定的库或技术,即便是强大的Angular,似乎也因为最近的一些事情而动摇。 2014年10月的ng-europe会议上,Angular开发者团队透露了一个关于...
2015-11-12
Android中Okhttp3实现上传多张图片同时传递参数
之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片。 最近做项目,打算换个方法上传图片。 Android发展到现在,Okhttp显得越来越重要,所以,这次我选择用Okhttp上传图片。 Okhttp目前已经更新到Okhttp...
2017-03-17
JavaScript实现PC手机端和嵌入式滑动拼图验证码三种效果
PC和手机端网站滑动拼图验证码效果源码,同时包涵了弹出式Demo,使用ajax形式提交二次验证码所需的验证结果值,嵌入式Demo,使用表单形式提交二次验证所需的验证结果值,移动端手动实现弹出式Demo三种效果 首先要确认前端使用页面,比如...
2017-03-17
Angular2-primeNG文件上传模块FileUpload使用详解
近期在学习使用Angular2做小项目,期间用到很多primeNG的模块。 本系列将结合实战总结angular2-primeNG各个模块的使用经验。 文件上传模块FileUploadModule 首先要在使用该组件的模块内导入文件上传模块 ...
2017-03-09
React.js编程思想
JavaScript框架层出不穷,在很多程序员看来,React.js是创建大型、快速的Web应用的最好方式。这一款由Facebook出品的JS框架,无论是在Facebook还是在Instagram中,它的表现都非常出色。 使用React.j...
2015-11-12
JavaScript常用特效chm下载
下载地址:JavaScript常用特效chm下载 对了,如果打开空白,在手册上右键属性解除锁定即可。 ...
2015-11-12
Vue.js组件tab实现选项卡切换
本文实例为大家分享了vue插件tab选项卡的具体代码,供大家参考,具体内容如下 效果图: 代码如下: <!DOCTYPE html> <html lang="en"> <head> ...
2017-03-13
v-charts | 饿了么团队开源的基于 Vue 和 ECharts 的图表工具
在使用echarts生成图表时,经常需要做繁琐的数据类型转化、修改复杂的配置项,v-charts的出现正是为了解决这个 痛点。基于Vue2.0和echarts封装的v-charts图表组件,只需要统一提供一种对前后端都友好的数据格式 设置简...
2018-05-24
ajax为什么令人惊异?ajax的优缺点
使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。 Ajax不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。就像DHT...
2015-11-12
three.js实现围绕某物体旋转
话不多说,请看代码: 可以拖动右上角观察变化 <!DOCTYPE html> <html lang="en" style="width: 100%; height:100%;"&gt...
2017-02-17
回到顶部