Promisification、微任务

前提摘要
Promise 对象的构造器(constructor)语法如下:
let promise = new
Promise(function(resolve, reject) {
// executor
});
传递给 new Promise的函数被称为 executor当 new Promise 被创建,executor 会自动运行。

Promisification

fication:使成为…,Promisification:使……成为promise
node.js常使用,promisify 是Node.js 标准库 util 模块中的一个函数,用于将遵循Node.js 回调风格的函数转换为返回Promise 的函数,可以使用 async/await 语法来等待异步操作完成,从而让异步代码看起来更像同步代码。

目的: 接受回调的函数 —————————> 一个 返回promise的函数
用法: loadScript(‘path/script.js’, (err, script) => {…} ) —————————> loadScriptPromise(‘path/script.js’).then(…)
在这里插入图片描述

promisify(f)

针对callback(err, result)只有两个参数的转化(最常用)

  1. 接受一个需要被 promise 化的函数 f,并返回一个包装函数(*)。
  2. 包装器返回一个 promise,并将调用转发给原始的 f,并在我们自定义的回调 (**) 中跟踪结果。
function promisify(f) {
  return function (...args) { // (*)    // ...args:src
    return new Promise((resolve, reject) => {
      function callback(err, result) { // 我们对 f 的自定义的回调 (**)
        if (err) {
          reject(err);
        } else {
          resolve(result);
        }
      }

      args.push(callback); // 将我们的自定义的回调附加到 f 参数args的末尾,args:[src, callback]
      f.call(this, ...args); // 调用原始的函数,
                             // call第一个参数this:调用原始函数时,保留原始函数(f)中对于 this 关键字的引用,保持上下文一致性。
    });
  };
}

// 用法:
let loadScriptPromise = promisify(loadScript); // 返回一个包装函数 *
loadScriptPromise(...).then(...);  // loadScriptPromise传入src

微任务

  • 同步代码是指在当前执行上下文中按顺序执行的代码,不涉及异步操作。当 JavaScript 引擎执行到同步代码时,会一行一行地顺序执行,不会等待其他代码或事件的完成。
  • 宏任务是指由 JavaScript 引擎放入任务队列中的任务。它们通常包括整个脚本、setTimeout、setInterval、DOM 事件等。宏任务会在当前执行栈中的所有同步代码执行完毕后才会被执行。

异步任务需要管理,ECMA 标准规定了一个内部队列 PromiseJobs,通常被称为“微任务队列(microtask queue)”。

  • 队列(queue)先进先出
  • 只有在 JavaScript 引擎中没有其它任务在运行时,才开始执行任务队列中的任务。

示例1

promise 的处理程序 .then、.catch 和 .finally 都是异步的。 当一个 Promise 准备就绪(即状态变为
resolved 或 rejected)时,它的 .then()、.catch()、.finally() 等处理程序会被放入微任务队列中。

let promise = Promise.resolve();

promise.then(() => alert("promise done!"));

alert("code finished"); // 这个 alert 先显示

解析:

  1. let promise = Promise.resolve(); 创建了一个已经 resolved 的 Promise 对象。
  2. promise.then(() => alert("promise done!")); 给这个 Promise 添加了一个 .then() 回调函数。这个回调函数会在 Promise 状态变为 resolved 时执行,并被放入微任务队列中。
  3. alert("code finished"); 同步代码立即执行,显示 “code finished” 这个 alert。
  4. 当前的同步代码执行完毕后,JavaScript 引擎会检查微任务队列。微任务队列中有一个任务,即在前一步中添加到 Promise 的 .then() 回调函数。
  5. 执行微任务队列中的任务,即执行 .then() 回调函数,显示 “promise done!” 。

示例2: 未处理的 rejection

每个宏任务之后,引擎会立即执行微任务队列中的所有任务,然后再执行其他的宏任务,或渲染,或进行其他任何操作。

let promise = Promise.reject(new Error("Promise Failed!"));
setTimeout(() => promise.catch(err => alert('caught')), 1000);

// Error: Promise Failed!
window.addEventListener('unhandledrejection', event => alert(event.reason));

解析:

  1. let promise = Promise.reject(new Error("Promise Failed!"))同步代码执行,创建了一个被reject的 Promise 对象。
  2. setTimeout 宏任务被触发,它会在至少 1 秒后将 回调函数添加到微任务队列中。
  3. window.addEventListener()同步执行,添加unhandledrejection 事件监听器,当 Promise 被拒绝且没有被捕获时,unhandledrejection 事件会作为一个宏任务被触发,显示“Promise Failed!”
  4. 所有同步代码执行完毕后,JavaScript 引擎开始执行微任务队列中的任务。这时,第二行代码中的回调函数promise.catch(err => alert('caught')) 被执行,它是一个微任务(会在当前宏任务执行完成后立即执行),显示“caught”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/435154.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

本地部署websocket服务端并结合内网穿透实现固定公网地址连接

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…

So you think you understand IP fragmentation?

文章目录 前言一、Why care?二、Prevention三、Well-understood?四、Introducing fragquiz五、A novel (?) algorithm六、Reader challenge七、traceroute八、ICMP参考资料 前言 本文来自:https://lwn.net/Articles/960913/ February 7, 2024This article was …

英福康INFICON真空计VGC012-103-401使用说明

英福康INFICON真空计VGC012-103-401使用说明

【C++ Primer Plus学习记录】break和continue语句

break和continue语句都使程序能够跳过部分代码。可以在switch语句或任何循环中使用break语句,使程序跳到switch或循环后面的语句处执行。continue语句用于循环中,让程序跳过循环体中余下的代码,并开始新一轮循环(参见图6.4&#x…

Unity性能优化篇(八) 导入的模型网格优化设置

模型导入Unity后,可以选中这个模型,在Inspector窗口设置它的属性。下面说的都是可自定义选择优化的地方 Model选择卡: 1.在Model选项卡,启用Mesh Compression可以压缩模型,压缩程度越高,模型精度越低,但是…

GEE 将裁剪后的Sentinel-2影像 在ArcGIS中去除空值

在ArcGIS中,可以使用栅格计算器(Raster Calculator)工具来设置NoData值为空。以下是在ArcGIS中将NoData值设置为空的步骤: 打开ArcGIS软件并加载下载的Sentinel-2影像数据。 影像Nodata空值以黑色背景呈现,影响矢量数据…

使用 Docker 部署 Stirling-PDF 多功能 PDF 工具

1)Stirling-PDF 介绍 大家应该都有过这样的经历,面对一堆 PDF 文档,或者需要合并几个 PDF,或者需要将一份 PDF 文件拆分,又或者需要调整 PDF 中的页面顺序,找到的线上工具 要么广告满天飞,要么 …

OpenCV与机器学习:OpenCV实现主成分分析

OpenCV实现主成分分析 前言主成分分析(PCA)数据生成画图cv2.PCACompute绘制主成分分析结果 前言 维数灾难是指出现一定数量的特征(或者维度)后,分类器的性能将开始下降。特征越多,数据集中的信息就越多。但…

当前爆火的:ChatGPT4、Claude3、Gemini、Sora、GPTs及AI领域中的集中大模型的最新技术

原文链接:当前爆火的:ChatGPT4、Claude3、Gemini、Sora、GPTs及AI领域中的集中大模型的最新技术 第一:2024年AI领域最新技术 1.最新超强模型Claude3使用 2.OpenAI新模型-GPT-5 3.谷歌新模型-Gemini使用 4.Meta新模型-LLama3 5.阿里巴巴…

[C语言]——C语言常见概念(1)

目录 一.C语言是什么、 二.C语言的历史和辉煌 三.编译器的选择(VS2022为例) 1.编译和链接 2.编译器的对比 3.VS2022 的优缺点 四.VS项目和源文件、头文件介绍 五.第⼀个C语言程序 ​​​​​​​ 一.C语言是什么、 ⼈和⼈交流使⽤的是⾃然语⾔&…

时间序列-AR MA ARIMA

一、AR模型(自回归) AR探索趋势和周期性 预测依赖于过去的观测值和模型中的参数。模型的阶数 p pp 决定了需要考虑多少个过去时间点的观测值。 求AR模型的阶数 p和参数 ϕ i \phi_i ϕi​ ,常常会使用统计方法如最小二乘法、信息准则(如AIC、BIC&#xf…

15:Zookeeper高可用集群|分布式消息队列Kafka|搭建高可用Hadoop集群

Zookeeper高可用集群|分布式消息队列Kafka|搭建高可用Hadoop集群 Zookeeper集群Zookeeper角色与特性Zookeeper角色与选举Zookeeper的高可用Zookeeper可伸缩扩展性原理与设计Zookeeper安装zookeeper集群管理 Kafka概述在node节点上搭建3台kafka 高可用Had…

EdgeX Foundry - 导出数据到 MQTT 服务

文章目录 一、概述1.安装说明2.安装 EMQX3.MQTTX 工具 二、安装部署1.docker-comepse2.修改配置3.启动 EdgeX Foundry4.访问 UI4.1. consul4.2. EdgeX Console 5.测试 EdgeX Foundry # EdgeX Foundryhttps://iothub.org.cn/docs/edgex/ https://iothub.org.cn/docs/edgex/devi…

数字化时代下的内部审计转型方法与步骤

内部审计是一种独立的、客观的确认和咨询活动,包括鉴证、识别和分析问题以及提供管理建议和解决方案。狭义的数字化转型是指将企业经营管理和业务操作的各种行为、状态和结果用数字的形式来记录和存储,据此再对数据进行挖掘、分析和应用。广义的数字化转…

HTML入门:简单了解 HTML 和浏览器

你好,我是云桃桃。今天来简单了解一下 HTML 以及浏览器。 HTML 是什么? HTML(全称:Hypertext Markup Language)是一种标记语言,用于创建和呈现网页的结构和内容。 它由一系列标签(或称为元素…

小程序API能力集成指南——画布API汇总(五)

CanvasContext canvas 组件的绘图上下文。 方法如下(4): setLineWidth CanvasContext.setLineWidth CanvasContext.setLineWidth(number lineWidth) 功能描述 设置线条的宽度 参数 number lineWidth 线条的宽度,单位 px…

论文研读_多目标部署优化:无人机在能源高效无线覆盖中的应用(ImMOGWO)精简版

此篇文章为Multi-objective Deployment Optimization of UAVs for Energy-Efficient Wireless Coverage的论文学习笔记,只供学习使用,不作商业用途,侵权删除。并且本人学术功底有限如果有思路不正确的地方欢迎批评指正! 创新点 RD算法 混合…

热红外图像直方图修正显示

热红外图像的直方图修正是一种用于增强图像对比度和可视化细节的技术。下面是一个使用Python和OpenCV库实现直方图均衡化的示例代码: import cv2 import numpy as np# 读取热红外图像 image cv2.imread(thermal_image.png, cv2.IMREAD_GRAYSCALE)# 对图像进行直方…

.NetCore6.0实现ActionFilter过滤器记录接口请求日志

文章目录 目的实现案例:一.首先我们新建一个WebApi项目二.配置 appsettings.json 文件,配置日志存放路径三.创建 Model 文件夹,创建AppConfig类和ErrorLog类1.在AppConfig类中编写一个GetConfigInfo方法获取配置文件中的值2.在ErrorLog类中&a…

JAVA虚拟机实战篇之内存调优[1](内存泄露和溢出概念、常见场景、解决思路)

文章目录 内存泄漏(memory leak)内存溢出(Out of Memory): 内存泄漏的常见场景场景一:未删除用户数据场景二:分布式任务调度 解决内存溢出解决内存溢出思路发现问题 – Top命令发现问题 – Visu…