大白话讲解Promise(二)理解Promise规范
术语
Promise
promise 是一个拥有 then
方法的对象或函数,其行为符合本规范;
thenable
是一个定义了 then
方法的对象或函数,文中译作“拥有 then
方法”;
值(value)
指任何 JavaScript 的合法值(包括 undefined
, thenable 和 promise);
异常(exception)
是使用 throw
语句抛出的一个值。
拒绝原因(reason)
表示一个 promise 的拒绝原因。
要求
等待态(Pending)
处于等待态时,promise 需满足以下条件:
- 可以迁移至完成态或拒绝态
- 不能迁移至其他任何状态
- 必须拥有一个不可变的终值
拒绝态(Rejected)
处于拒绝态时,promise 需满足以下条件:
- 不能迁移至其他任何状态
- 必须拥有一个不可变的据因
这里的不可变指的是恒等(即可用 ===
判断相等),而不是意味着更深层次的不可变(译者注: 盖指当 value 或 reason 不是基本值时,只要求其引用地址相等,但属性值可被更改)。
Then 方法
一个 promise 必须提供一个 then
方法以访问其当前值、终值和据因。
then
方法接受两个参数:onFulfilled
和 onRejected
都是可选参数。
- 如果
onFulfilled
不是函数,其必须被忽略 - 如果
onRejected
不是函数,其必须被忽略
onFulfilled
特性
如果 onFulfilled
是函数:
- 当
promise
执行结束后其必须被调用,其第一个参数为promise
的终值 - 在
promise
执行结束前其不可被调用 - 其调用次数不可超过一次
onRejected
特性
如果 onRejected
是函数:
- 当
promise
被拒绝执行后其必须被调用,其第一个参数为promise
的据因 - 在
promise
被拒绝执行前其不可被调用 - 其调用次数不可超过一次
调用时机
onFulfilled
和 onRejected
只有在执行环境堆栈仅包含平台代码时才可被调用 注1
调用要求
onFulfilled
和 onRejected
必须被作为函数调用(即没有 this
值)注2多次调用
then
方法可以被同一个 promise
调用多次
- 当
promise
成功执行时,所有onFulfilled
需按照其注册顺序依次回调 - 当
promise
被拒绝执行时,所有的onRejected
需按照其注册顺序依次回调
返回
then
方法必须返回一个 promise
对象 注3onFulfilled
或者 onRejected
返回一个值 x
,则运行下面的 Promise 解决过程:[[Resolve]](promise2, x)
- 如果
onFulfilled
或者onRejected
抛出一个异常e
,则promise2
必须拒绝执行,并返回拒因e
- 如果
onFulfilled
不是函数且promise1
成功执行,promise2
必须成功执行并返回相同的值 - 如果
onRejected
不是函数且promise1
拒绝执行,promise2
必须拒绝执行并返回相同的据因
Promise 解决过程
Promise 解决过程 是一个抽象的操作,其需输入一个 promise
和一个值,我们表示为 [[Resolve]](promise, x)
,如果 x
有then
方法且看上去像一个 Promise ,解决程序即尝试使 promise
接受 x
的状态;否则其用 x
的值来执行 promise
。
这种 thenable 的特性使得 Promise 的实现更具有通用性:只要其暴露出一个遵循 Promise/A+ 协议的 then
方法即可;这同时也使遵循 Promise/A+ 规范的实现可以与那些不太规范但可用的实现能良好共存。
运行 [[Resolve]](promise, x)
需遵循以下步骤:
x
与 promise
相等
如果 promise
和 x
指向同一对象,以 TypeError
为据因拒绝执行 promise
x
为 Promise
如果 x
为 Promise ,则使 promise
接受 x
的状态 注4:
- 如果
x
处于等待态,promise
需保持为等待态直至x
被执行或拒绝 - 如果
x
处于完成态,用相同的值执行promise
- 如果
x
处于拒绝态,用相同的据因拒绝promise
.then(function(data){
.then(function(data){
console.log(data);
return runAsync3();
})
x
为对象或函数
如果 x
为对象或者函数:
- 把
x.then
赋值给then
注5 - 如果取
x.then
的值时抛出错误e
,则以e
为据因拒绝promise
- 如果
then
是函数,将x
作为函数的作用域this
调用之。传递两个回调函数作为参数,第一个参数叫做resolvePromise
,第二个参数叫做rejectPromise
: - 如果
resolvePromise
以值y
为参数被调用,则运行[[Resolve]](promise, y)
- 如果
rejectPromise
以据因r
为参数被调用,则以据因r
拒绝promise
- 如果
resolvePromise
和rejectPromise
均被调用,或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用 - 如果调用
then
方法抛出了异常e
: - 如果
resolvePromise
或rejectPromise
已经被调用,则忽略之 - 否则以
e
为据因拒绝promise
- 如果
- 如果
then
不是函数,以x
为参数执行promise
- 如果
- 如果
x
不为对象或者函数,以x
为参数执行promise
如果一个 promise 被一个循环的 thenable 链中的对象解决,而 [[Resolve]](promise, thenable)
的递归性质又使得其被再次调用,根据上述的算法将会陷入无限递归之中。算法虽不强制要求,但也鼓励施者检测这样的递归是否存在,若检测到存在则以一个可识别的TypeError
为据因来拒绝 promise
注6。
注释
注1 这里的平台代码指的是引擎、环境以及 promise 的实施代码。实践中要确保
onFulfilled
和onRejected
方法异步执行,且应该在then
方法被调用的那一轮事件循环之后的新执行栈中执行。这个事件队列可以采用“宏任务(macro-task)”机制或者“微任务(micro-task)”机制来实现。由于 promise 的实施代码本身就是平台代码(译者注: 即都是 JavaScript),故代码自身在处理在处理程序时可能已经包含一个任务调度队列或『跳板』)。译者注: 这里提及了 macrotask 和 microtask 两个概念,这表示异步任务的两种分类。在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。
两个类别的具体分类如下:
- macro-task: script(整体代码),
setTimeout
,setInterval
,setImmediate
, I/O, UI rendering micro-task:
process.nextTick
,Promises
(这里指浏览器实现的原生 Promise),Object.observe
,MutationObserver
详见 stackoverflow 解答 或 这篇博客
- macro-task: script(整体代码),
注2 也就是说在 严格模式(strict) 中,函数
this
的值为undefined
;在非严格模式中其为全局对象。注3 代码实现在满足所有要求的情况下可以允许
promise2 === promise1
。每个实现都要文档说明其是否允许以及在何种条件下允许promise2 === promise1
。注4 总体来说,如果
x
符合当前实现,我们才认为它是真正的 promise 。这一规则允许那些特例实现接受符合已知要求的 Promises 状态。注5 这步我们先是存储了一个指向
x.then
的引用,然后测试并调用该引用,以避免多次访问x.then
属性。这种预防措施确保了该属性的一致性,因为其值可能在检索调用时被改变。- 注6 实现不应该对 thenable 链的深度设限,并假定超出本限制的递归就是无限循环。只有真正的循环递归才应能导致
TypeError
异常;如果一条无限长的链上 thenable 均不相同,那么递归下去永远是正确的行为。
相关文章:

量子计算机人类意识云,意识上传-人类距离永生还要多久(大脑的工作原理很有可能与量子计算机一致)...
事情的引子是最近的科幻电影《炭变》, 300年后,人类意识上传到数字植入物(称为“堆栈”)中,并且富人还可以不停的升级,并基本上永远活着。虽说这只是部科幻电影,但也会让很多人流口水,毕竟如果有可能实现永…

Alpha混合
Direct3D计算Alpha混合的颜色公式:Color ( SrcRGB * SrcK ) ( DestRGB * DestK )SrcRGB表示源颜色值,即将要绘制的颜色值。SrcK表示源混合系数,通常赋值为D3DBLEND_SRCALPHA,即当前绘制像素的Alpha值DestRGB表示目标颜色值&…

考研计算机专业课怎么复习,2016考研计算机专业课如何复习?
2016考研计算机专业课如何复习??基础复习阶段以指定参考书为主,兼顾笔记,进行专业课的第一轮复习。看书要以理解为主,不必纠缠于细节,并在不懂的知识点处做上标记。第一步,选择一本难度适宜、内容全面、与…

Linux 学习手记(1):命令行BASH的基本操作
1. Shell 是什么 Shell(壳)是用户与操作系统底层(通常是内核)之间交互的中介程序,负责将用户指令、操作传递给操作系统底层。 Shell一般分为:图形化Shell(GUI)、命令行Shell…

为了智能驾驶,李彦宏要改造城市道路了!
10 月 18 日,在世界智能网联汽车大会上,百度 CEO 李彦宏提到:当汽车变得越来越智能,道路的基础设施也必须跟着变,必须进行改造。 李彦宏在发言中表示,“很多自动驾驶汽车都是需要依赖极其昂贵的激光雷达来…

LoadRunner Winsock 10053错误的真正原因
最近使用LoadRunner进行Winsock协议的性能测试时,测试的WebServer是JBoss,经常出现10053错误,现象如下:当我用lrs_create_socket创建连接之后,当这个socket连接的请求次数达到100次后,这个连接就不可用了&a…

dsp和通用计算机的区别,dsp芯片是什么_dsp芯片和通用微处理器有什么区别
对于dsp芯片很多人都会比较陌生,它主要运用在信号处理、图像处理、声音语言等多个场所。那么dsp芯片到底是什么呢?它和通用微处理器有什么不同。接下来小编就简单的给大家介绍一下dsp芯片是什么及dsp芯片和通用微处理器有什么区别。一、dsp芯片是什么1、…
百度大脑发布企业服务解决方案,将 AI 技术落实到细分领域
人工智能竞争之势愈演愈烈,AI与场景应用的深度结合将成为各家企业的取胜关键。10月18日,百度大脑行业创新论坛在北京正式拉开帷幕,届时将走进全国6个城市举办7场以企业服务、信息服务和零售等为主题的专题活动,展示人工智能与不同…

图片上传(加水印、缩略图、远程保存)的简单例子
图片上传(加水印、缩略图、远程保存)的简单例子(应用于51aspx.com)该源码下载地址:http://51aspx.com/CV/ImageUpload今天看到xiongeee发的文章使用使用FileUpload控件上传图片并自动生成缩略图、自动生成带文字和图片的水印图 …

wp实例开发精品文章源码推荐
qianqianlianmengwp实例开发精品文章源码推荐 WP8 启动媒体应用 这个示例演示了如何选择正确的msAudioCategory类别的音像(AV)流来配置它作为一个音频播放流。具体地说,这个示例执行以下操作:启动一个媒体应用与“媒体”msA……资源地址: http://www.apkbus.…

98级计算机应用教材,西安外事学院98级计算机应用9806班毕业二十年校友返校
7月28日,计算机应用9806班的校友们赴二十年之约,相聚于西安外事学院工学院。出席此次会议的有工学院党总支书记、副院长任国良、计算机应用9806班当年的老师赵培华、张凤琴、刘可、刘挺以及计算机应用9806班的学生。会议之前,校友们参观了学校…

js:appendChild、insertBefore和insertAfter
web/Win8开发中经常要在js中动态增加一些element,就需要用到下面的一些方法: appendChild: target.appendChild(newChild) newChild作为target的子节点插入最后的一子节点之后 insertBefore: target.insertBefore(newChild,existi…

来呀!AI喊你斗地主——首个搞定斗地主的深度神经网络
参加 2018 AI开发者大会,请点击 ↑↑↑ 作者 | Anonymous authors 译者 | 蔡志兴 编辑 | Jane 出品 | AI科技大本营 【导读】近年来,从围棋到 Dota 团战赛,深度神经网络应用在各种游戏竞赛中不断取得突破。这一次,有人把这种方…

在 Django 的 View 中利用 function decorator 可实现一定程度的代码重用
在 Django 中,假设有几个 view, 他们都接受类似的参数,做类似的处理,最后又输出类似的变量到模板中配合显示,唯一不同的就是模板路径。 最普通的写法可能是这样: defview_a(request, some_id): some_obj SomeClass.…

Linux---管理网络
一、ip基础知识1.ipv42进制32位-----10进制 172.25.0.10/255.255.255.0172.25.0.10:ip地址255.255.255.0:子网掩码子网掩码255位对应的ip位为网络位子网掩码0对应的ip位为主机位二、主机联网主机有两块网卡:有线和无线;࿰…

网络丢包现象分析处理指导书5
sniffer简明教程 xiong2127 51cto技术博客sniffer是由NAI公司提供的强大的协议分析仪,完整的sniffer系统,除了我们经常使用的以太网模块外,还具有广域网模块,广域网模块需要专用的硬件支持。比如E1/FR/POS/ATM等,均需要…

信息与计算机科学考研学校排名,计算机科学与技术考研学校排名
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼排名 学校名称 评估结果1 北京大学 A2 清华大学 A3 浙江大学 A4 国防科技大学 A5 北京航空航天大学 A6 北京邮电大学 A7 哈尔滨工业大学 A8 上海交通大学 A9 南京大学 A10 华中科技大学 A11 电子科技大学 A12 北京交通大学 A-13 北…

800万中文词,腾讯AI Lab开源大规模NLP数据集
参加 2018 AI开发者大会,请点击 ↑↑↑ 10 月19 日,腾讯 AI Lab 宣布开源大规模、高质量的中文词向量数据。该数据包含 800 多万中文词汇。 腾讯 AI Lab 表示,相比现有的公开数据,该数据在覆盖率、新鲜度及准确性上大幅提高&#…

屏幕后处理——Bloom
来自于《Unity Shader 入门精要》书本的学习 先上图 代码分3部分 1.PostEffectsBase.cs using System.Collections; using System.Collections.Generic; using UnityEngine; //在编辑器状态下可执行该脚本来查看效果 [ExecuteInEditMode] //屏幕后处理特效一般需要绑定在摄像…

服务端口大全+注解
端口:0服务:Reserved说明:通常用于分析操作系统。这一方法能够工作是因为在一些系统中“0”是无效端口,当你试图使用通常的闭合端口连接它时将产生不同的结果。一种典型的扫描,使用IP地址为0.0.0.0,设置ACK…

双绞线是计算机网络的一种通信线路吗,计算机网络环境的信道传输技术分析
韩长军【摘要】计算机网络的产生对人类文明进步树立了新标杆,促进了人们的交流,对于人类社会信息获得的途径以及咨询传播方式等等也产生了极其重大的影响。数据密集程度较高的科学和工程,比如、水文观测、地壳波动资料、气象行业等等…

为了智能驾驶,李彦宏要改造城市道路
10 月 18 日,在世界智能网联汽车大会上,百度 CEO 李彦宏提到:当汽车变得越来越智能,道路的基础设施也必须跟着变,必须进行改造。 李彦宏在发言中表示,“很多自动驾驶汽车都是需要依赖极其昂贵的激光雷达来实…

美团大脑:知识图谱的建模方法及其应用 | 公开课笔记
参加 2018 AI开发者大会,请点击 ↑↑↑分享嘉宾 | 王仲远(美团 AI Lab NLP 中心负责人)整 理 | 周翔出 品 | AI科技大本营作为人工智能时代最重要的知识表示方式之一,知识图谱能够打破不同场景下的数据隔离,为搜…

LINQ篇:ASP.NET using LINQ(Part One) Scott大师的产物
【原文地址】Using LINQ with ASP.NET (Part 1) 【原文发表日期】Sunday, May 14, 2006 9:49 PM 最近使我激动不已的新鲜事之一就是LINQ系列技术的出现,包括LINQ,DLINQ,XLINQ和不久后的其他技术。 LINQ将被完全集成到代号为Orcas的下个版本Vi…

大学生如何合理使用计算机,大学生计算机合理使用引导分析
摘 要:在当今社会中,计算机已经成为大家工作与生活不可缺少的工具。而在大学校园内,越来越多的学生也拥有了自己的计算机。计算机不仅可以帮助大学生进行学习活动,还能使学生在紧张学习之余进行娱乐放松。但是,大学生在…

关于机器学习中山峰聚类算法的说明
前言在之前关于聚类算法的文章中,笔者主要涉及的内容均是和参数求解相关的,如C均值(包括模糊C均值)、混合高斯模型等,而对于一些无参数密度估计的算法尚未讨论,而且一般基于参数密度估计的算法均是建立在假…

SQLDMO- (数据备份与恢复篇)
引用usingSystem;usingSystem.Collections.Generic;usingSystem.Text;publicsealedclassDbOper { /**//// <summary> /// DbOper类的构造函数 /// </summary> private DbOper() { } /**//// <summary> /// 数据库备份 /// </summary> …

详细介绍Java垃圾回收机制
垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再使用的对…

美国卡尔顿学院计算机专业怎么样,美国卡尔顿学院排名
在学术上,卡尔顿学院在美国处于领先地位。被美国新闻与世界报道评为全美前10位的文理学院卡尔顿学院排名卡尔顿学院是明尼苏达州菲尔德市一所历史悠久的文科私立院校,一直奉行无宗教派别男女合校制度。卡尔顿学院始建于1866年,经过一百多年的…
比特大陆发力边缘计算,详解终端AI芯片BM1880
作者 | 中国科学院微电子研究所 剑白 前不久比特大陆推出其云端人工智能芯片--SOPHON(算丰)BM1682芯片,BM1682是比特大陆设计,并对图像、视频等处理给予额外辅助支持的人工智能硬件加速芯片,其峰值运算速度为3TFLOPs,可提供给用户…