Promise面试题

news2025/1/11 14:04:37

Promise面试题,带你搞懂同步异步执行顺序

  • 前置知识
  • 面试题
    • 面试题一
    • 面试题二
    • 面试题三
    • 面试题四
  • 分析
    • 面试题一分析
    • 面试题二分析
    • 面试题三分析
    • 面试题四分析



在这里插入图片描述

前置知识

Promise中的then方法
then:指定用于得到成功value的成功回调和用于得到失败reason的失败回调,并且将放回一个新的Promise实例化对象
成功的状态:执行then方法的第一个回调函数 失败的状态:执行then方法的第二个回调函数

then方法的返回值是Promise实例化对象,其状态取决于回调函数的内容

  • 如果返回的为非Promise实例化对象,则得到一个成功的Promise
  • 如果返回的是Promise实例化对象,则Promise实例化对象的状态和结果值将直接影响result常量的状态和结果值
  • 如果为抛出异常,则新的Promise实例化对象(result)为失败的Promise

JS中用来存储待执行回调函数的队列中包含了两个特定的队列
宏队列:用来保存执行的宏任务(回调),比如:定时器、DOM时间操作,ajax操作
微队列:用来保存执行的微任务(回调),比如:promise(then catch finally)
JS执行的时候会区分两个队列

  1. 首先JS引擎会先将所有的同步代码都执行完
  2. 接着在每次准备取出第一个宏任务的执行之前,都需要将所有的微任务一个一个取出来执行
  • 顺序为:同步任务<–微任务<–宏任务

在这里插入图片描述

事件循环的执行顺序可以概括为以下几个步骤(以下答案来自ChatGPT):

  1. 执行同步任务(同步代码),直到执行栈为空。
  2. 执行微任务队列中的所有微任务。微任务包括Promise的回调函数、MutationObserver的回调函数等。
  3. 更新渲染(如果需要)。
  4. 执行下一个宏任务。
    在上述步骤中,微任务队列的执行在渲染之前,也在下一个宏任务之前。这意味着微任务具有更高的优先级,可以在下一个宏任务之前立即执行。

面试题

面试题一

etTimeout(()=>{
	console.log(1);
 },0)
 Promise.resolve().then(()=>{
     console.log(2);
 })
 Promise.resolve().then(()=>{
     console.log(3);
 })
 console.log(4);

//答案:... 

面试题二

setTimeout(()=>{
    console.log(1);
})
new Promise(resolve=>{
    console.log(2);
    resolve()
}).then(()=>{
    console.log(3);
}).then(()=>{
    console.log(4);
})
console.log(5);
//答案:...

面试题三

const first = () => (new Promise((resolve,reject)=>{
    console.log(1);
    let p = new Promise((resolve,reject)=>{
        console.log(2);
        setTimeout(()=>{
            console.log(3);
            resolve(4)
        },0)
        resolve(5)
    })
    resolve(6)
    p.then(arg=>{
        console.log(arg);
    })
}))
first().then(arg=>{
    console.log(arg);
})
console.log(7);
//答案:...

面试题四

在这里插入图片描述

setTimeout(()=>{
     console.log(0);
 },0)
 new Promise((resolve,reject)=>{
     console.log(1);
     resolve();
 }).then(()=>{  //片段一
     console.log(2);
     new Promise((resolve,reject)=>{
         console.log(3);
         resolve();
     }).then(()=>{
         console.log(4);
     }).then(()=>{
         console.log(5);
     })
 }).then(()=>{  // 片段二
     console.log(6);
 })
 new Promise((resolve,reject)=>{
     console.log(7);
     resolve();
 }).then(()=>{  // 片段三
     console.log(8);
 })
 //答案:...

分析

面试题一分析

打印输出:4 2 3 1
分析:定时器为宏任务,加入宏任务队列;then方法为异步任务且为微任务,加入微任务队列;console.log打印输出为同步任务,直接打印输出4。由于微任务队列执行先于宏任务队列,因此先考虑2和3的打印输出,此处由入微任务队列先后顺序而定,先输出2,然后输出3,最后考虑输出宏任务队列的1,虽然其延迟时间为0。

  • 同步任务:4
  • 微任务:2 3
  • 宏任务:1

面试题二分析

打印输出:2 5 3 4 1

分析:定时器为宏任务,加入宏任务队列;new Promise为同步任务,执行函数体内resolve方法,首先打印输出2,然后更改Promise实例对象状态为成功;then方法为异步任务,且为微任务,加入微任务队列;console.log打印处处为同步任务,直接打印输出5;因此首先,打印输出同步任务2和5,然后考虑微任务队列,两个then方法执行先后由队列中顺序而定,输出3和4,最后考虑宏任务队列,打印输出1。

  • 同步任务:2 5
  • 微任务:3 4
  • 宏任务:1

面试题三分析

打印输出:1 2 7 5 6 3

分析:定义first函数为同步任务,执行其函数体,在new Promise的实例化方法中,首先执行同步输出1;定义p为一个Promise实例对象也为同步任务,执行函数体,首先打印输出2;定时器为宏任务,加入宏任务队列;执行resolve(5),更改p的状态为成功;执行resolve(6),更改外层Promise实例对象状态为成功;then方法为微任务,加入微任务队列;执行打印输出7。因此目前先执行同步任务,打印输出1、2和7,然后考虑微任务列队里执行先后,由于resolve(5)已更改p的状态为成功,因此首先输出arg:5,然后由于resolve(6)已更改外层Promise实例对象状态为成功,因此输出arg:6,因此目前执行微任务队列,打印输出5和6,最后考虑宏任务队列,打印输出3,但注意此时不会执行resolve(4)再去更改p的状态,因此状态已经由pending变为 resolved。

  • 同步任务:1 2 7
  • 微任务:5 6
  • 宏任务:3

面试题四分析

打印输出:1 7 2 3 8 4 6 5 0

分析:定时器为宏任务,加入宏任务队列;执行new Promise同步任务,首先打印输出1,接着执行resolve更改其实例化对象的状态为成功;then方法为微任务,加入微任务队列;继续执行new Promise同步任务,首先打印输出7,接着执行resolve更改其实例化对象状态为成功;then方法为微任务,加入微任务队列。因此目前首先执行同步任务,输出1和7,然后考虑微任务队列里执行先后顺序,由于已更改第一个Promise实例对象状态为成功,因此执行其链式调用then方法的第一个回调函数,首先打印输出2,接着执行new Promise函数体,首先打印输出3(微任务里),接着执行resolve,更改其实例化对象的状态为成功。由于then方法是异步的,当片段一(代码中已标出)代码没有执行完,片段二是不会执行的,转而会执行片段三,由于执行片段三前已执行resolve,其实例对象状态已变为成功,因此执行片段三的then方法中第一个回调,输出8,接着回到片段一里的第一个then方法,由于已经执行resolve,其实例对象状态已变为成功,因此执行then方法,输出4,此时若片段一中第一个then没有执行完,也不会接着链式执行第二个then。因此接着执行片段二,由于片段一的then方法没有return,因此执行完then的返回值为undefined,当返回值为非Promise对象:undefined时,则得到一个成功的Promise,且其[[PromiseResult]]为undefined,则可以执行then的第一个回调,输出6,同理回到片段一里的第二个then,输出5,最后执行宏队列任务,输出0

重难点:3之后输出8,4之后输出6,是因为then方法是异步的,前一个没有执行完,会接着往下走

  • 同步任务:1 7
  • 微任务:2 3 8 4 6 5
  • 宏任务:0

then方法是异步执行,就是当【.then()】前的方法执行完后再执行【then()】内部的程序
这样就避免了数据没获取到等的问题,语法为【promise.then(onCompleted,onRejected)】。

在这里插入图片描述

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

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

相关文章

openldap2.4版本管理员文档中文翻译版

OpenLDAP2.4管理员指南 文章目录 1.OpenLDAP介绍2.快速开始指南1.获得软件2.解压压缩包3.阅读文档4.运行configure5.编译软件6.测试编译结果7.安装软件8.编辑配置文件9.导入数据库配置10.启动slapd11.添加初始条目到目录中12.检测添加结果 3.大图片-配置选择1.本地目录服务2.带…

抓取微信小程序源码教程,扒微信小程序文件等

前言&#xff1a; 想成为一名微信小程序的开发者&#xff0c;前端思路的学习和安全意识是非常有必要的&#xff0c;故务必掌握小程序反编译技能。这里用到了2个工具《包解密》与《反编译》&#xff08;非原创&#xff0c;均来自网上的大佬&#xff09;&#xff0c;特别适合新手…

5.23黄金是否会继续下跌?多单被套怎么办?

近期有哪些消息面影响黄金走势&#xff1f;今日黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周二&#xff08;5月23日&#xff09;亚市盘中&#xff0c;现货黄金小幅走弱&#xff0c;一度刷新两日低点至1960美元/盎司&#xff0c;美国明尼亚波利斯联储主席卡…

redis的主从复制、哨兵、集群

主从复制&#xff1a; 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(Master)&#xff0c;后者称为从节点(Slave)&#xff1b;数据的复制是单向的&#xff0c;只能由主节点到从节点。 原理&#xff1a; 主从关系确定…

【VLAN如何划分?6个方法帮你解决!好用又简单!】

如何选择交换机&#xff1f;如何根据项目确定网络结构&#xff1f;交换机做为大家工作中最常用的设备之一&#xff0c;关于它的选择&#xff0c;不得不知。 在做项目时都有这样的疑问&#xff0c;因为参数决定了项目预算&#xff0c;常用的园区组网技术也是多种多样。 我们来…

物联网调试管理平台

1. 项目介绍 1.1 项目简介 MQTT调试管理平台是一款基于Spring Spring MVC Mybatis开发的一款物联网设备调试管理平台。 其功能主要是对客户MQTT调试页面进行集中管理&#xff08;连接信息、发送信息&#xff09;&#xff0c;系统管理员可在后台添加客户和调试页面&#xf…

OpenHarmony支持HDMI接口声卡适配说明

高清多媒体接口&#xff08;High Definition Multimedia Interface&#xff0c;HDMI &#xff09;是一种全数字化视频和声音发送接口&#xff0c;可以发送未压缩的音频及视频信号。HDMI可用于机顶盒、DVD播放机、个人计算机、电视、游戏主机、综合扩大机、数字音响与电视机等设…

chatgpt赋能Python-python_js解密

Python与JavaScript解密之道 在现代Web应用程序中&#xff0c;JavaScript和Python是两种最强大和流行的编程语言。Python具有强大的基于文本的处理和数据结构&#xff0c;而JavaScript则具有处理DOM&#xff0c;Ajax和动态效果的能力。然而&#xff0c;有时我们需要使用这两种…

Spring Cloud Eureka 是什么?如何使用它来实现服务注册与发现?

Spring Cloud Eureka 是什么&#xff1f;如何使用它来实现服务注册与发现&#xff1f; 在微服务架构中&#xff0c;服务注册与发现是一个非常重要的概念。它可以帮助我们实现服务的自动发现和负载均衡&#xff0c;从而提高系统的可用性和可扩展性。Spring Cloud Eureka 是一个…

无需公网IP,在家SSH远程连接公司内网服务器「cpolar内网穿透」

文章目录 视频教程1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 转载自cpolar内网穿透的文章&#xff1a;无公网IP&#xff0c;SSH远程连接Linux CentOS【内网穿透】 本次教程我们来实现如何在外公网环境下&am…

探索Java面向对象编程的奇妙世界(二)

⭐ 对象和类的详解⭐ 构造方法(构造器 constructor)⭐ 构造方法的重载⭐ 面向对象的内存分析 ⭐ 对象和类的详解 类可以看做是一个模版&#xff0c;或者图纸&#xff0c;系统根据类的定义来造出对象。我们要造一个汽车&#xff0c;怎么样造&#xff1f;类就是这个图纸&#xff…

以太网、工业以太网和Profinet三者有何关联?

总的来说&#xff0c;以太网是一种局域网规范&#xff0c;工业以太网是应用于工业控制领域的以太网技术&#xff0c;Profinet是一种在工业以太网上运行的实时技术规范。 下面&#xff0c;我们来详细说说这三者的区别。 1.以太网 以太网是当今现有局域网采用的最通用的通信协议…

AndResGuard 源码解析

背景 抖音包体积优化提出的“键常量池裁剪”是基于腾讯的AndResGuard资源混淆之后做的进一步处理&#xff0c;也就是对resources.arsc文件的处理。而资源混淆&#xff0c;就是对resources.arsc文件进行修改。那么我们可以尝试基于这个思路&#xff0c;对AndResGuard插件源码进…

推荐一款好用的Idea热部署插件

目录 1.什么是热部署 2.为什么需要热部署 3.热部署产品 3.1.JRebel 3.2.IDEA HotSwap 3.3.HotSwapAgent 3.4.Spring Boot DevTools 3.5.FastHotSwapper 4.FastHotSwapper安装使用 参考&#xff1a; 1.什么是热部署 热部署&#xff08;Hot Deployment&#xff09;是指…

chatgpt赋能Python-python_iloc_loc

使用Python中的iloc和loc方法对数据进行索引 如果你正在使用Python来进行数据处理或者数据分析&#xff0c;那么你肯定会遇到需要对数据进行索引的情况。Python提供了两个非常有用的方法——iloc和loc&#xff0c;对于数据的索引和切片操作非常实用。在本文中&#xff0c;我们…

yolov5-7.0 添加BiFPN

1. BiFPN特征融合 BiFPN是目标检测中神经网络架构设计的选择之一&#xff0c;为了优化目标检测性能而提出。主要用来进行多尺度特征融合&#xff0c;对神经网络性能进行优化。来自EfficientDet: Scalable and Efficient Object Detection这篇论文。 在这篇论文中&#xff0c;作…

算法27:从暴力递归到动态规划(2)

上一题比较简单&#xff0c;下面来一道比较难的题目。 假设有排成一行的N个位置&#xff0c;记为1~N&#xff0c;N 一定大于或等于 2 开始时机器人在其中的M位置上(M 一定是 1~N 中的一个) 如果机器人来到1位置&#xff0c;那么下一步只能往右来到2位置&#xff1b; 如果机…

初级程序员如何快速晋升为技术大牛

[请搜索公众号“云智AI助手”、“云智博瑞”关注我们 │ 谢谢支持 ] Cloud wisdom, AI assistant 作为初级程序员&#xff0c;你是否常常遇到代码优Bug调试的难题&#xff1f;幸运的是&#xff0c;ChatGPT可以助你一臂之力。本文将通过多个实例展示&#xff0c;如何借ChatGPT的…

【微信支付】分享一个失败的项目

这个项目是去年做的&#xff0c;开始客户还在推广&#xff0c;几个月后发现服务器已经关掉了。这是一个发图片猜谜语的应用&#xff0c;用户猜对了分红包&#xff0c;所得奖金可以提现。开发的时候对需求都不太看好&#xff0c;觉得用户粘性太低了。今天就把所有的程序拿了出来…

[抢先看] 全平台数据 (数据库) 管理工具 DataCap 1.10.0

推荐一个基于 SpringBoot 开发的全平台数据 (数据库管理工具) 功能比较完善&#xff0c;建议下载使用: github.com/EdurtIO/datacap 目前已经支持 40 多种数据源。国内首个应用 ChatGPT 到数据管理系统中项目。 在 DataCap v1.10.0 中我们主要核心修改了数据编辑器&#xff0c;…