好家伙,本篇为《JS高级程序设计》第十章“期约与异步函数”学习笔记

1.非重入期约

1.1.可重入代码(百度百科)

先来了解一个概念

可重入代码(Reentry code)也叫纯代码(Pure code)是一种允许多个进程同时访问的代码。

为了使各进程所执行的代码完全相同,故不允许任何进程对其进行修改。

程序在运行过程中可以被打断,并由开始处再次执行,并且在合理的范围内(多次重入,而不造成堆栈溢出等其他问题),

程序可以在被打断处继续执行,且执行结果不受影响。

                                            ----来自百度百科

 

1.2.非重入期约

非重入期约方法 期约进入 落定(解决/拒绝)状态时,与该状态相关的处理程序不会立即执行 ,

处理程序后的 同步代码 会在其之前 先执行 ,该特性称为非重入

当期约进入落定状态时,与该状态相关的处理程序仅仅会被排期,而非立即执行。

跟在添加这个处 理程序的代码之后的同步代码一定会在处理程序之前先执行。

即使期约一开始就是与附加处理程序关联 的状态,执行顺序也是这样的。

这个特性由 JavaScript 运行时保证,被称为“非重入”(non-reentrancy) 特性。

let promise = new Promise(() => {
console.log("5")
}) // 创建一个期约并将解决函数保存在一个局部变量中
let p = new Promise((resolve) => {
synchronousResolve = function () {
console.log('1');
resolve();
console.log('2');
};
synchronousResolve();
});
p.then(() => console.log('4'));
console.log('3');

看到了吗,这里4依旧被放在了最后输出

这说明在这个例子中,即使期约状态变化发生在添加处理程序之后,处理程序也会等到运行的消息队列让 它出列时才会执行。

2.邻近处理程序的执行顺序

如果给期约添加了多个处理程序,当期约状态变化时,相关处理程序会按照添加它们的顺序依次执行

let p1 = Promise.resolve();
p1.then(() => setTimeout(console.log, 0, 1));
p1.then(() => setTimeout(console.log, 0, 2));
p1.then(() => setTimeout(console.log, 0, 3));
p1.then(() => setTimeout(console.log, 0, 4));

 

3.期约连锁

把期约逐个地串联起来是一种非常有用的编程模式。

之所以可以这样做,是因为每个期约实例的方 法(then()、catch()和 finally())都会返回一个新的期约对象,

而这个新期约又有自己的实例方,这样连缀方法调用就可以构成所谓的“期约连锁”

你应该能想象到,这就是一长串then(),( then()、catch()和 finally()都行 )

let p = new Promise((resolve, reject) => {
resolve();
});
p.then(() => console.log('1'))
.then(() => console.log('2'))
.then(() => console.log('3'))
.then(() => console.log('4'));

 

4.期约合成

这肯定是个将多个期约合成为一个的某个特性(废话)

Promise 类提供两个将多个期约实例组合成一个期约的静态方法:Promise.all()和 Promise.race()。

而合成后期约的行为取决于内部期约的行为。

4.1.Promise.all()

特性一:合成的期约只会在每个包含的期约都解决之后才解决

特性二:如果至少有一个包含的期约待定,则合成的期约也会待定。

如果有一个包含的期约拒绝,则合成的 期约也会拒绝

let p1 = Promise.all([
Promise.resolve(),
new Promise((resolve, reject) => {
resolve();
})
]);
console.log("I'm p1");
console.log(p1); // 一次拒绝会导致最终期约拒绝
let p2 = Promise.all([
Promise.resolve(),
Promise.reject(),
Promise.resolve()
]);
console.log("I'm p2");
console.log(p2); let p3 = Promise.all([
Promise.resolve(),
new Promise(() => {}),
Promise.resolve()
]);
console.log("I'm p3");
console.log(p3);

 

4.2.Promise.race()

Promise.race()不会对解决或拒绝的期约区别对待。

无论是解决还是拒绝,只要是第一个落定的 期约,Promise.race()就会包装其解决值或拒绝理由并返回新期约

let p1 = Promise.race([
Promise.resolve(),
new Promise((resolve, reject) => {
resolve();
})
]);
console.log("I'm p1");
console.log(p1); // 一次拒绝会导致最终期约拒绝
let p2 = Promise.race([
Promise.resolve(),
Promise.reject(),
Promise.resolve()
]);
console.log("I'm p2");
console.log(p2); let p3 = Promise.race([
Promise.resolve(),
new Promise(() => {}),
Promise.resolve()
]);
console.log("I'm p3");
console.log(p3);

 

5.课后练习

1.什么是promise期约连锁?

  答:Promise期约连锁调用是使用Promise的一种技术,它可以让你把多个Promise以链式的方式组合起来,每个Promise的结果作为下一个Promise的输入。

这样可以把复杂的操作分解成一系列简单的操作,以便更容易理解和管理。

2.如何解释Promise的的非重入特性?

  答:非重入期约方法 期约进入 落定(解决/拒绝)状态时,与该状态相关的处理程序不会立即执行 ,

处理程序后的 同步代码 会在其之前 先执行 ,该特性称为非重入

第125篇: 期约Promise基本特性的更多相关文章

  1. JavaScript中的Promise【期约】[未完成]

    JavaScript中的Promise[期约] 期约主要有两大用途 首先是抽象地表示一个异步操作.期约的状态代表期约是否完成. 比如,假设期约要向服务器发送一个 HTTP 请求.请求返回 200~29 ...

  2. java提高篇-----理解java的三大特性之封装

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  3. (转载)OC学习篇之---类的三大特性:封装,继承,多态

    之前的一片文章介绍了OC中类的初始化方法和点语法的使用,今天来继续学习OC中的类的三大特性,我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这个也是介绍类的时候,必须提到的话题,那么今 ...

  4. OC学习篇之---类的三大特性(封装,继承,多态)

    之前的一片文章介绍了OC中类的初始化方法和点语法的使用:http://blog.csdn.net/jiangwei0910410003/article/details/41683873,今天来继续学习 ...

  5. iOS开发——新特性OC篇&Swift 2.0新特性

    Swift 2.0新特性     转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度 ...

  6. .NET进阶篇03-Reflection反射、Attribute特性

    知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂 内容目录 一.概述二.反射1.反射使用2.创建对象3.调用方法4.字段属性三.特性四.总结 一.概述 反射其实无处不在,我们用VS进行调试时候, ...

  7. 前端知识点回顾之重点篇——ES6的Promise对象

    Promise Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异 ...

  8. [python学习篇][廖雪峰][1]高级特性--创建生成器 方法2 yield

    def fib(max): n, a, b = 0, 0, 1 while n < max: print b a, b = b, a + b n = n + 1 将print b 改成yield ...

  9. [python学习篇][廖雪峰][1]高级特性--创建生成器 方法1 a = (x for x in range(1,3))

    创建一个生成器的方法: for x in range(1,10000000) ,先生成一个列表[1........9999999] 如果我们只想要后面的几个元素,会发现浪费很多空间.所以,如果列表元素 ...

  10. [python学习篇][廖雪峰][1]高级特性--列表生成式

    >>> import os >>> [d for d in os.listdir(r"d:\temp")] ['0.png', '0.xml', ...

随机推荐

  1. Semantic Kernel 通过 LocalAI 集成本地模型

    本文是基于 LLama 2是由Meta 开源的大语言模型,通过LocalAI 来集成LLama2 来演示Semantic kernel(简称SK) 和 本地大模型的集成示例. SK 可以支持各种大模型 ...

  2. echarts饼状图不要中间的文字提示

    饼状图不要中间的文字提示信息 emphasis: { label: { show: false, //将这个设置为false }, }, 为什么饼状图不要中间的问题提示信息 因为有些时候,在文字很多的 ...

  3. Go 匿名函数与闭包

    Go 匿名函数与闭包 匿名函数和闭包是一些编程语言中的重要概念,它们在Go语言中也有重要的应用.让我们来详细介绍这两个概念,并提供示例代码来帮助理解. 目录 Go 匿名函数与闭包 一.匿名函数(Ano ...

  4. vim 从嫌弃到依赖(21)——跨文件搜索

    之前介绍了vim中的搜索模式,使用正则表达式可以很方便的在一个文件中进行搜索.后续也介绍了如何使用 argsdo 命令在参数列表中进行替换操作.但是到目前为止还没有介绍如何在工程目录中进行搜索,而这个 ...

  5. 基于 hugging face 预训练模型的实体识别智能标注方案:生成doccano要求json格式

    强烈推荐:数据标注平台doccano----简介.安装.使用.踩坑记录_汀.的博客-CSDN博客_doccano huggingface官网 参考:数据标注平台doccano----简介.安装.使用. ...

  6. 2.7 CE修改器:多级指针查找

    在本步骤中,你需要使用多级指针的概念来查找健康值真正的地址并修改它.多级指针就是一个指针的指针,也就是第一个指针指向第二个指针,第二个指针指向第三个指针,以此类推,最终指向你想要访问的地址. 首先,你 ...

  7. FFmpeg的录制命令

    FFmpeg的录制命令 命令的作用 它可以捕捉桌面窗口,摄像头的视频流和麦克风的音频流. 命令的格式 ffmpeg [输入格式] [输入选项] -i [输入设备索引] [输出选项] 输出文件 其中输入 ...

  8. window下部署单机hadoop环境

    window本地部署单机hadoop,修改配置文件和脚本如下,只记录关键配置和步骤,仅供参考 hadoop-2.6.5 spark-2.3.3 1.配置文件core-site.xml <conf ...

  9. VB6的Office颜色菜单 - 开源研究系列文章

    今天把VB6里面的源码开源了( VB6各类源码开源 - 开源研究系列文章 ),这次把原来VB6里面的一个菜单控件进行介绍,需要的网友请下载安装: 1.看使用截图: 运行时截图: 设计时截图: 2.Of ...

  10. 【算法】【回溯】两道经典排列问题OJ详解【力扣46 力扣47】【超详细的回溯算法教程】让我们牢牢把握回溯的精髓

    [算法][回溯]两道经典排列问题OJ详解[力扣46 力扣47][超详细的回溯算法教程]让我们牢牢把握回溯的精髓 作者: @小小Programmer 这是我的主页:@小小Programmer 在食用这篇 ...