Promise魔鬼面试题

文章目录

    • 题目
    • 解析
      • 难点分析
      • 分析输出
        • step1
        • step2
        • step3
        • step4
        • step5
        • step6

参考/致谢:渡一袁老师

题目

Promise.resolve().then(() => {console.log(0);return Promise.resolve(4);}).then((res) => {console.log(res);});Promise.resolve().then(() => {console.log(1);}).then(() => {console.log(2);}).then(() => {console.log(3);}).then(() => {console.log(5);}).then(() => {console.log(6);});

解析

难点分析

  1. 这题难点就在于 return Promise.resolve(4) 当返回一个 Promise 的时候是如何处理的,在 Promise a+ 规范中,写道,如图:

    image-20240508012830269

  2. 也就是说这个当前Promise(表示return Promise了的当前这个Promise) 要与返回的 Promise 保持一致,但是如何保持一致,标准里面并没有说到,也就说实际如何实现这个状态一致,并不关心,在 v8 中,实现的源码如图:

    image-20240508013128678

  3. 表示的意思是如果返回的是 Promise,它会去调用这个 Promise 的 then 方法,在这个 then 方法里面完成当前 Promsie,但是调用 then 方法完成当前这个 Promise 是会放入到一个微任务队列里面去完成的

  4. 至此,这个难点就已经分析完成了

分析输出

step1

我们回到题目本身,来分析一下输出,我们知道,一个 then 方法一定会返回一个 Promise,then 方法是同步的,then 方法里面的回调才是异步的,根据这个准则,我们可以先来确定一下初步的执行状态。

根据这个准则,执行的初步顺序如下:

  1. 第一个 Promise.reslove():记作 pr1,状态为 fulfilled
  2. then(()=>{console.log(0)}):记作 p0,状态为 pending,因为这些then里面的回调函数还是异步任务,目前处于执行then方法的同步阶段,因此未执行也就无法确定 Promise 的状态,后续 pending 同理
  3. then((res)=>{console.log(res)}):记作 pres
  4. 第二个 Promise.reslove():记作 pr2,状态为 fulfilled
  5. then(()=>{console.log(1)}):记作 p1,状态为 pending
  6. then(()=>{console.log(2)}):记作 p2,状态为 pending
  7. then(()=>{console.log(3)}):记作 p3,状态为 pending
  8. then(()=>{console.log(5)}):记作 p5,状态为 pending
  9. then(()=>{console.log(6)}):记作 p6,状态为 pending

图解如下:

image-20240508023258080

step2

此时同步执行完成,只有两个 Promise 状态完成,这两个函数开始执行,首先就会输出 0,然后根据前面分析的规则,如果返回的是一个 Promise,就会调用这个 Promise的then方法,且是放入一个微队列中执行,这里的 Promise.resolve(4) 记作 p4,那么使用一个伪代码表示即为 addMicrotask(p4.then(()=>完成p0)),为什么是完成呢?这里的返回的事 Promise.resolve(),所以在 then 里面是完成 p0,演变图解如下:

image-20240508023559162

step3

现在输出已经可以看到是 0,那么将微队列里面的任务开始执行,p1 的状态也会变为 fulfilled,然后将会输出 1,输出 1 之后

p1 变为 fulfilled 之后就会执行下一个 then 方法里面的成功回调,在这里也就是()=>{console.log(2)},而同理,这个回调也需要加入到微队列,即在 p4.then(()=>完成p0) 后加入

而 p4.then(()=>完成p0),其实需要执行只是()=>完成p0这一部分,then 方法里面的回调会加入到微队列,所以又会向后加入一个微任务,也就是在 ()=>{console.log(2)} 此回调后面,图解如下:

image-20240508023633702

step4

我们继续分析执行结果,执行p4.then(),将里面的回调加入到微队列,那么就会按照顺序执行 console.log(2),p2 变为 fulfilled,紧接着输出 2,输出 2 之后,同理将 ()=>{console.log(3)} 加入到微队列

执行 ()=>完成p0,会将 p0 的状态也变为 fulfilled,p0 变为 fulfilled 之后,就会把 p0 后续的 then(即pres) 加入到微队列,图解如下:

image-20240508024300933

step5

根据结果执行微队列里面的任务,同理 p3 也变为 fulfilled,然后就会输出 3,同时将 p3 下一个 then 方法的回调(即p5)加入到微队列。

然后执行 (res)=>{console.log(res)},同理 pres 状态为 fulfilled,控制台输出 4

res 为什么是 4?Promise a+ 规范,如果返回的是 promise,则下一个 then 方法的执行的回调和结果由这个返回的 Promise 决定,图解如下:

image-20240508025843267

step6

那后续的输出就是一样的了,输出 5,同理 p5 的状态为 fulfilled,将 p6 的回调加入微队列,然后执行,输出 6,完成 p6,最后程序执行结果如图:

image-20240508030258847

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【BUUCTF】Crypto_RSA(铜锁/openssl使用系列)

【BUUCTF】Crypto_RSA(铜锁/openssl使用系列) 1、题目 在一次RSA密钥对生成中,假设p473398607161,q4511491,e17 求解出d作为flga提交 2、解析 RSA加密过程: 1)选择素数:选择两个不…

【管理咨询宝藏93】大型制造集团数字化转型设计方案

【管理咨询宝藏93】大型制造集团数字化转型设计方案 【格式】PDF版本 【关键词】国际咨询公司、制造型企业转型、数字化转型 【核心观点】 - 235页大型制造型集团数字化转型方案设计!细节非常详尽,图表丰富! - 系统架构必须采用成熟、具有国…

docker资源限额

多数的应⽤场景要对Docker容器的运⾏内存进⾏限制,防⽌其使⽤过多的内存。 格式:-m或--memory 正常的内存大小 [rootadmin ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS …

SpringBoot过滤器简单构建详细教程以及与拦截器区别解释

作用范围:过滤器基于Servlet规范,作用于更广泛的层面,不仅限于Spring MVC,它可以拦截进入Web应用的所有请求,包括静态资源请求。过滤器可以对请求和响应的内容进行预处理和后处理。实现方式:过滤器需要实现…

Java初识继承

继承 文章目录 继承为什么需要继承继承中变量的访问特点继承中方法的访问特点继承的优缺点 概念:在Java中,继承是面向对象编程的一个基本特性。它允许我们定义一个新类,它从另一个已经存在的类继承其属性和方法。被继承的类称为父类或超类,新…

牛客NC142 最长重复子串【中等 字符串 Java/Go】

题目 题目链接: https://www.nowcoder.com/practice/4fe306a84f084c249e4afad5edf889cc 思路 注意:题目给的时间复杂度是O(N^2)那么直接套用双重循环:外层循环i为假定起始重复子串的初始位置,内层循环的j为假定重复子串的结束位置…

Mac 链接 HP 136w 打印机步骤

打开 WI-FI 【1】打开打印机左下角Wi-Fi网络设计【或者点击…按钮进入WI-FI菜单】,找到NetWork选项OK进入; 【2】设置WI-FI选项:在菜单内找到Wi-Fi选项OK进入; 【3】在菜单内找到Wi-Fi Direct选项OK进入; 【4】在菜单…

(论文阅读-分析引擎)Modin

一、简介 目标是在不改变的Dataframe语义的情况下支持可扩展的dataframe操作。 什么是机会主义评价?Opportunistic Evaluation? Exploratory data analysis(EDA):总结、理解并从数据集中获取价值的过程。 MPI&#…

【知识点随笔分享 | 第十篇】快速介绍一致性Hash算法

前言: 在分布式系统中,数据的分布和负载均衡是至关重要的问题。一致性哈希算法是一种解决这些挑战的有效工具,它在分布式存储、负载均衡和缓存系统等领域得到了广泛应用。 随着互联网规模的不断扩大,传统的哈希算法在面对大规模…

PY32MD310单片机介绍,非常适合做三相/单相 BLDC/PMSM主控

PY32MD310 单片机采用了高性能的 32 位 ARM Cortex-M0 内核,嵌入高达 64 Kbytes flash 和 8 Kbytes SRAM 存储器,最高工作频率 48 MHz。芯片内置多功能三相 PN 型半桥式栅极驱动器,片内集成多路 I2C、SPI、USART 等通讯外设,1 路 …

爬虫学习:XPath匹配网页数据

目录 一、安装XPath 二、XPath的基础语法 1.选取节点 三、使用XPath匹配数据 1.浏览器审查元素 2.具体实例 四、总结 一、安装XPath 控制台输入指令:pip install lxml 二、XPath的基础语法 XPath是一种在XML文档中查找信息的语言,可以使用它在HTM…

【快捷部署】022_ZooKeeper(3.5.8)

📣【快捷部署系列】022期信息 编号选型版本操作系统部署形式部署模式复检时间022ZooKeeper3.5.8Ubuntu 20.04tar包单机2024-05-07 一、快捷部署 #!/bin/bash ################################################################################# # 作者&#xff…

接入大量设备后,视频汇聚系统EasyCVR安防监控视频融合平台是如何实现负载均衡的?

一、负载均衡 随着技术的不断进步和监控需求的日益增长,企业视频监控系统的规模也在不断扩大,接入大量监控设备已成为一项常态化的挑战。为确保企业能够有效应对这一挑战,视频汇聚系统EasyCVR视频融合平台凭借其卓越的高并发处理能力&#x…

mac安装linux的centos strem9 虚拟机解压rar文件报错

背景:解压rar文件需要再linux上安装unrar工具 yum install unrar直接安装的后解压报错,如图 解决办法: 下载:wget https://www.rarlab.com/rar/rarlinux-x64-6.0.2.tar.gz 安装: tar -zxvf rarlinux-x64-6.0.2.tar.gz cd rar …

AutoDev for VSCode 预览版:精准 AI 编程提示词与编辑器的完美融合

在过去的一个月里,我在休着陪产假、看娃的同时,也在闲暇时间里设计了 AutoDev for VSCode 的架构。 我们将 AutoDev for Intellij IDEA 平台的非凡开发者体验带到了 VSCode 平台。在 IDEA 版本中通过构建非常精准的提示词,以及与编辑器的完美…

GNU Radio创建时间戳 C++ OOT块

文章目录 前言一、创建自定义的 C OOT 块1、创建 timestamp_sender C OOT 模块①、创建 timestamp_sender OOT 块②、修改 C 代码 2、创建 timestamp_receiver C OOT 模块①、创建 timestamp_receiver OOT 块②、修改 C 代码 3、创建 delayMicroSec C OOT 模块①、创建 delayMi…

Apple OpenELM设备端语言模型

Apple 发布的 OpenELM(一系列专为高效设备上处理而设计的开源语言模型)引发了相当大的争论。一方面,苹果在开源协作和设备端AI处理方面迈出了一步,强调隐私和效率。另一方面,与微软 Phi-3 Mini 等竞争对手相比&#xf…

k8s部署Kubeflow v1.7.0

文章目录 环境介绍部署访问kubeflow ui问题记录 环境介绍 K8S版本:v1.23.17,需要配置默认的sc 参考:https://github.com/kubeflow/manifests/tree/v1.7.0 部署 #获取安装包 wget https://github.com/kubeflow/manifests/archive/refs/tag…

数控六面钻适用场景-不止家具制造

在快节奏的现代生活中,家具作为我们生活的重要组成部分,其美观度和实用性日益受到人们的关注。而在这背后,一个不可或缺的“工匠”正默默地发挥着它的作用——那就是数控六面钻。 数控六面钻,顾名思义,是一种高度自动…

Ansible自动运维工具之playbook

一.inventory主机清单 1.定义 Inventory支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内。 2.变量 (1)主机变量 [webservers] 192.168.10.14 ansible_port22 ansible_userroot ans…