前端翻译:Promises/A+规范

简介:

原文地址:https://promisesaplus.com/

本篇为原文翻译+个人理解,若有谬误请各位指正,谢谢。

尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/4139172.html  ^_^肥仔John

 

一个可靠的可共同协作的JavaScript Promise开放标准

  promise代表一个异步操作的最终结果。主要通过promise的then方法订阅其最终结果的处理回调函数,和订阅因某原因无法成功获取最终结果的处理回调函数。

  本说明将详述then方法的行为特点,符合Promise/A+规范的promise实现均以then方法为交互核心。Promises/A+组织会因新发现的问题以向后兼容的方式修改规范,且每次修改均会经过严格的考虑、讨论和测试,因此Promises/A+规范相对来说还是比较稳定的。

  Promises/A+是在Promises/A的基础上对原有规范进行修正和增强。

  最后,本说明并不涉及如何创建、fulfill或reject promises,而是着重介绍then方法。将来或许在其他说明中涉及这些内容。

1. 术语                                        

  1.1. "promise"拥有then方法且符合Promises/A+标准的对象。

  1.2. "thenable"拥有thne方法的对象。

  1.3. "value"合法的JavaScript对象(包括undefined,thenable对象,promise对象)。

  1.4. "exception"通过throw语句抛出的值。

  1.5. "reason"合法的JavaScript对象,表示promise状态转换为rejected的原因。

2. 需求                                        

  2.1. Promise状态

    promise状态为pending,fulfilled和rejected中的其中一种。

    2.1.1. 当promise状态为pending时:

       2.1.1.1. promise的状态可以转换为fulfilled或rejected。

  2.1.2. 当promise状态为fulfilled时:

       2.1.2.1. 无法转换为其他状态。

       2.1.2.2. 必须有一个不可改变的值作为onFulfilled事件处理函数的入参

    2.1.3. 当promsie状态为rejected时:

   2.1.2.1. 无法转换为其他状态。

       2.1.2.2. 必须有一个不可改变的值作为onRejected事件处理函数的入参

    上述不可改变的值是指value或reason变量所存储的值或地址不变,而不是指地址所指向的堆空间内的对象属性等不可变。

  2.2. then方法

    promise必须提供then方法用于订阅状态转换事件,从而获取最终值或失败原因。

    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的不可变值将作为 onFulfilled函数 的入参。

      2.2.2.2. 在promise状态转换为fulfilled前禁止被调用。

      2.2.2.3. 只能被调用一次。

    2.2.3.  如果 onRejected 为函数时:

      2.2.3.1. 当且仅当promise状态为rejected时才能被调用(晚绑定依然会被调用),并且promise的不可变值将作为 onRejected函数 的入参。

      2.2.3.2. 在promise状态转换为rejected前禁止被调用。

      2.2.3.3. 只能被调用一次。

    2.2.4.  onFulfilled 和 onRejected 当且仅当执行上下文栈中仅包含平台代码[3.1]时才执行

    2.2.5.  onFulfilled 和 onRejected 必须以函数的形式来调用(也就是 this对象 在sloppy模式下为全局对象,strict模式下为undefined)[3.2]

    2.2.6.  同一个promise的then方法可被多次调用

      2.2.6.1. 当promise状态为fulfilled时,将按调用then方法的顺序执行 onFulfilled函数 。

      2.2.6.2. 当promise状态为rejected时,将按调用then方法的顺序执行 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将执行 reject(e) 。

      2.2.7.3. 如果 promise1的 onFulfilled 不是函数,那么promise1的不可变值将传递到promise2并作为promise2的不可变值。

      2.2.7.4. 如果 promise1的 onRejected不是函数,那么promise1的不可变原因将传递到promise2并作为promise2的不可变原因,并作为promise2的 onRejected 的入参。

  2.3. Promise处理过程

     Promise处理步骤是对表示形式为 [[Resolve]](promise, x) 的状态事件处理函数的返回值的抽象处理。如果x为thenable对象,由于thanble对象的行为特性类似于一个promise实例,因此让x来设置promise的状态。若x为其他类型则设置promise的状态为fulfilled并且不可变值为x。

     [[Resolve]](promise, x) 的处理过程如下:

    2.3.1. 如果promise和x指向同一个对象,则将promise的状态转换为rejected并且以TypeError作为不可变原因。

    2.3.2. 如果x是一个promise实例,则以x的状态作为promise的状态[3.4]

  2.3.2.1. 如果x的状态为pending,那么promise的状态也为pending,直到x的状态变化而变化。

      2.3.2.2. 如果x的状态为fulfilled,promise的状态也为fulfilled,并且以x的不可变值作为promise的不可变值。

      2.3.2.3. 如果x的状态为rejected,promise的状态也为rejected,并且以x的不可变原因作为promise的不可变原因。

    2.3.3. 如果x是对象或函数

      2.3.3.1. 将x.then赋值给变量then[3.5]

      2.3.3.2. 如果在获取属性x.then时抛出异常,则将promise的状态转换为rejected并且以e作为promise的不可变原因。

      2.3.3.3. 如果then为函数类型,则以x作为then函数内部的this指针,以promise的resolvePromise和rejectPromise作为入参调用then函数。

        2.3.3.3.1. 如果以y作为入参调用resolvePromise,那么则执行Promise处理过程 [[Resolve]](promise, y) 。

            2.3.3.3.2. 如果以r作为入参调用rejectPromise,那么则将promise状态转换为rejected并且以r作为promise的不可变原因。

     2.3.3.3.3. resolvePromise和rejectPromise仅有一个能被调用,且仅能调用一次,重复调用均视作无效操作。

     2.3.3.3.4. 如果调用then方法抛出异常

      2.3.3.4.1. 如果resolvePromise或rejectPromise已经被调用后才抛出异常,则无视。

      2.3.3.4.2. 其他情况则将promise状态转换为rejected并且以异常对象e作为promise的不可变原因。

       2.3.3.4. 如果then不是函数,则将promise状态转换为fulfilled并且以x作为promise的不可变值。

    2.3.4.如果x不是对象或函数,则将promise状态转换为fulfilled并且以x作为promise的不可变值。

    假如不断以Promise或thenable作为onFulfilled的返回值,那么就会进入Promise处理过程的死循环中,虽然Promise/A+规范并没有明确规定具体实现需要通过对死循环进行返回TypeError异常的处理,但实现者可以自行考虑该情况的处理方式。[3.6]

3. 备注                                        

  3.1. 这里的“平台代码”是指引擎、执行环境和promise实现代码。实际上,是要求 onFulfilled 和 onRejected 函数为异步执行。浏览器可通过 setTimeout 或 setImmediate ,nodejs可通过 MutationObserver 或 process.nextTick 将函数调度到event loop队列中达到异步执行的效果。

  3.2. 在strict模式下this指针为undefined,而在sloppy模式下this指针为全局对象。

  3.3. 具体实现可允许promise2===promise1,并且需要将promise2===promise1的条件以文档形式标注说明。

  3.4. x为真正的promise实例。

  3.5. 由于考虑到ES5的getter特性可能会产生副作用,因此在获取x.then属性时,应该形如以下方式,防止多次调用x.then。

var then = x.then;
typeof(then) === 'function' && then.call(x, resolvePromise, rejectPromise)

  3.6.具体实现武断地限制Promise处理过程的递归深度,只有真正的死循环才抛出TypeError异常。如果允许无限循环,也是没问题的。

 版权所有:Promises/A+组织

如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!

分类: JavaScript, 翻译
1
0
« 上一篇: JS魔法堂:剖析源码理解Promises/A规范
» 下一篇: JS魔法堂:jsDeferred源码剖析
posted @ 2014-12-03 15:00 ^_^肥仔John 阅读( 4838) 评论( 0) 编辑 收藏
 
相关文章
|
1月前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
122 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
9月前
|
前端开发 JavaScript API
前端代码书写规范
前端代码规范提升项目可维护性和团队协作效率。关注项目命名清晰简洁、一致性,组件命名使用驼峰式且具描述性。JS遵循4空格缩进,分号结束语句,CSS按逻辑排序,HTML注重语义化。注释要功能性、文档化且简洁。遵循规范能减少错误,增强团队沟通。
345 3
|
6月前
|
前端开发 JavaScript 开发工具
前端规范
前端规范
|
4月前
|
前端开发 测试技术
如何从零到一建立前端规范
【10月更文挑战第6天】
115 2
|
5月前
|
监控 前端开发 开发者
前端代码规范 - 日志打印规范
前端代码规范 - 日志打印规范
|
6月前
|
缓存 JavaScript 前端开发
|
6月前
|
前端开发
前端代码书写规范
【8月更文挑战第15天】前端代码书写规范
204 0
|
9月前
|
缓存 JavaScript 前端开发
前端 JS 经典:CommonJs 规范
前端 JS 经典:CommonJs 规范
77 0
|
9月前
|
前端开发
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
【Web前端】CSS基本语法规范和引入方式&&常见选择器用法&&常见元素属性
|
9月前
|
前端开发 数据安全/隐私保护
开发指南016-前端图标规范
平台为了保证统一性,做了很多约定,例如按钮图标等

热门文章

最新文章

  • 1
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    详解智能编码在前端研发的创新应用
  • 4
    智能编码在前端研发的创新应用
  • 5
    VSCode AI提效工具,通义灵码前端开发体验
  • 6
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 8
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
  • 9
    【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
  • 10
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
  • 1
    前端起dev从110秒减少到7秒, 开发体验大幅提升
    17
  • 2
    无前端经验如何快速搭建游戏站:使用 windsurf 从零到上线的详细指南
    33
  • 3
    【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
    39
  • 4
    VSCode AI提效工具,通义灵码前端开发体验
    95
  • 5
    开箱即用的GO后台管理系统 Kratos Admin - 前端权限
    13
  • 6
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    47
  • 7
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
    84
  • 8
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    36
  • 9
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    159
  • 10
    详解智能编码在前端研发的创新应用
    122