ECMAScript 6 - 通过Promise输出题理解Promise

1 题目(1)

题目背景:分享@洛千陨 珍藏题

const p1 = () => (new Promise((resolve, reject) => {console.log(1);let p2 = new Promise((resolve, reject) => {console.log(2);const timeOut1 = setTimeout(() => {console.log(3);resolve(4);}, 0)resolve(5);});resolve(6);p2.then((arg) => {console.log(arg);});}));
const timeOut2 = setTimeout(() => {console.log(8);const p3 = new Promise(reject => {reject(9);}).then(res => {console.log(res)})
}, 0)p1().then((arg) => {console.log(arg);
});
console.log(10);
输出结果:1 2 10 5 6 8 9 3

输出结果分析
思路:同步->异步

宏任务队列:8 9 3 4
(8-9这一块都是属于setTimeout里面的,下一轮 Event Loop再执行;resolve(5)后不输出4)

微任务队列:5 6
(为什么先5后6, 因为在p2定义的时候会执行promise内部的代码, resolve(5)时有下面p2.then接收就会打印5)

JS主线程-同步代码:1 2 10

注意点

  1. p1是个返回1个promise对象的普通函数需要p1()执行,p1().then接收回调;p2是个promise对象,p2.then接收回调。
  2. Promise 第一个参数是成功时的回调resolve, reject只是变量名。
    const p3 = new Promise(reject => {
    reject(9);
    }).then(res => {
    console.log(res)
    })

延伸变形

const p1 = () => (new Promise((resolve, reject) => {console.log(1);resolve(6);let p2 = new Promise((resolve, reject) => {console.log(2);const timeOut1 = setTimeout(() => {console.log(3);resolve(4);}, 0)resolve(5);});p2.then((arg) => {console.log(arg, 'p2 then');});}));p1().then((arg) => {console.log(arg,'p1 then');
});
console.log(10);
输出结果:1 2 10 5 6 8 9 3

问题为什么'6'在'5'前面还是先输出'5' ?!!
:这里p1()调用->执行了p2.then,再执行p1.then,所以’5’比’6’先输出
在这里插入图片描述

2 题目(2)

题目背景:手写题 - 实现一个带并发限制的异步调度器

class Scheduler {constructor(max) {this.max = maxthis.count = 0 this.queue = new Array() }async add(promiseCreator) {if (this.count >= this.max) {await new Promise((resolve, reject) => {this.queue.push(resolve)})}this.count++const res = await promiseCreator()this.count--if (this.queue.length) {this.queue.shift()()}console.log('res: ', res)return res}
}
const timeout = (time) => new Promise(resolve => {console.log('100')setTimeout(resolve, time)
})const scheduler = new Scheduler(2)
const addTask = (time, order) => {scheduler.add(() => timeout(time)).then(() => {console.log(order); return 'timeout'})
}addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4')
输出结果:
100
100res: undefined
100
2res: undefined
100
3res: undefined
1res: undefined
4

输出结果分析

  • Part 1:
    (1)addTask1000、addTask500:
    走两次到这儿
    this.count++
    const res = await promiseCreator(); 都输出’100’,先打印2个'100'
    (2)addTask300、addTask400:
    /** 这个new Promise单纯只是为了创建个微任务去等,前面加了await,没有resolve()是不会往下走的 */
    await new Promise((resolve, reject) => {
    this.queue.push(resolve);
    });
  • Part 2:
    (3)500ms的timeout先执行完,setTimeout(resolve, time) resolve后面木有具体值,∴res: undefined
    (4)∵this.queue.shift()()即resolve()是同步代码,
    addTask300走到这儿
    this.count++
    const res = await promiseCreator();
    ∴先打印下一个'100'再return res打印'2'
  • Part 3:
    (5)接下来同理,300ms的timeout先执行完,setTimeout(resolve, time) resolve后面木有具体值,∴res: undefined
    (6)∵this.queue.shift()()即resolve()是同步代码,
    addTask400走到这儿
    this.count++
    const res = await promiseCreator();
    ∴先打印下一个'100'再return res打印'3'
  • Part 4:
    (7)1000ms的timeout先执行完,setTimeout(resolve, time) resolve后面木有具体值,∴res: undefined
    (8)没有下一个’100’了,return res打印'1'
  • Part 5:
    (9)400ms的timeout执行完,setTimeout(resolve, time) resolve后面木有具体值,∴res: undefined
    (10)没有下一个’100’了,return res打印'4'

在这里插入图片描述

Promise基本概念

可参考我的另外一篇博客:ECMAScript 6 Promise - Promise

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

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

相关文章

【前端框架React】原理

React设计思想 1.原生JS React相比于vue来说更接近原生JS,因为在react内部,jsx模板经babel转化后是一个对象,所有的操作都是基于这个对象和其对应的fiber结构来操作的,而vue.js通过编译将templete模板转换成渲染函数(render),执…

工具系列:TensorFlow决策森林_(3)使用dtreeviz可视化

文章目录 介绍设置安装 TF-DF 和 dtreeviz导入库 可视化分类树加载、清洗和准备数据分割训练/测试集并训练模型训练一个随机森林分类器显示决策树检查叶节点统计信息决策树如何对实例进行分类特征空间划分 可视化回归树加载、清洗和准备数据分割训练/测试集并训练模型训练一个随…

漏洞处理-未设置X-Frame-Options

漏洞名称&#xff1a;iFrame注入 风险描述&#xff1a;系统未设置x-frame-options头 风险等级&#xff1a;低 整改建议&#xff1a;为系统添加x-frame-options头 知识 X-Frame-Options 响应头 X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在 <fram…

一体式读卡器:引领数据读取新潮流

一体式读卡器&#xff1a;引领数据读取新潮流 随着科技的发展&#xff0c;读卡器在各个领域的应用越来越广泛&#xff0c;如工业自动化生产、身份认证、门禁控制、数据采集等。读卡器主要有两种类型&#xff1a;一体式读卡器和分体式读卡器。这两种类型的读卡器各有其优缺点&a…

带你读懂SoBit 跨链桥教程

从BTC网络到Solana网络桥接BRC20 1.打开SoBit平台&#xff1a;在您的网络浏览器中启动SoBit Bridge应用程序。 2.连接您的钱包&#xff1a; 选择SoBit界面右上角的比特币网络来连接您的数字钱包。 3.选择源链、目标链和您想桥接的代币&#xff1a; 从下拉菜单中选择’BTC’作为…

通过 conda 安装 的 detectron2

从 detectron2官网 发现预编译的版本最高支持 pytorch1.10、cuda11.3。&#xff08;2023-12-26&#xff09; 1、安装 conda 环境。 conda create --name detectron2 python3.8 2、安装 pytorch1.10 和 cuda11.3。 pip3 install torch1.10.0cu113 torchvision0.11.1cu113 torc…

有哪些备份策略?具体该如何实施这些备份方案?

在目前的时代背景下&#xff0c;个人和企业都需要重视数据备份这项措施&#xff0c;因为它是一个能够有效保护重要数据安全不丢失的方法。随着社会的发展&#xff0c;数据备份情况日益复制&#xff0c;我们逐渐开始采用不同的备份策略来对不同的数据进行备份&#xff0c;从而更…

Mysql(5日志备份恢复)

一.日志管理 MySQL 的日志默认保存位置为 /usr/local/mysql/data 先看下mysql的日志文件有无&#xff1a; 修改配置文件添加&#xff1a;错误日志&#xff0c;用来记录当MySQL启动、停止或运行时发生的错误信息&#xff0c;默认已开启 修改配置文件添加&#xff1a;通用查…

如何查看NX UI对话框内的控件(使用UIFW侦查)

一、概述 在NX二次开发中有很多命令从界面上看起开相似&#xff0c;但实质确不同&#xff0c;个人人为一是出于对软件产权的保护&#xff0c;增加二次开发的难度&#xff0c;二是由于NX在不断地发展和版本交替中为了保留老用户的操作习惯&#xff0c;故意用新控件做成老控件的…

SANSAN新鲜事|工业物联网最热门的应用方向,你都了解吗

引言 在现代工业&#xff0c;随着新基建、智慧、数字化转型等一系列国家倡议和政策的推动&#xff0c;一场无声的数字革命正在持续展开。 在本文中&#xff0c;我们将讨论工业物联网(IIoT)的应用&#xff0c;从制造工厂到能源电网&#xff0c;从物流到农业&#xff0c;IIoT正在…

blackbox黑盒监控部署(k8s内)

一、前言 部署在k8s中需要用到deployment、configmap、service服务 二、部署 创建存放yaml的目录 mkdir /opt/blackbox-exporter && cd /opt/blackbox-exporter 编辑blackbox配置文件&#xff0c;使用configmap挂在这 vi configmap.yaml apiVersion: v1 kind: Confi…

vue虚拟列表展示

效果图 <template><!-- 总体高度区域 --><divref"listWrap"class"m-container"scroll"scrollListener"><div:style"handleContainerHeight()"><!-- 可视区域 --><divclass"m-area":style&…

MySQL——运维篇

三、运维篇&#x1f6a9; 1. 日志&#x1f37b; 1.1 错误日志 错误日志记录了当mysql启动和停止时&#xff0c;以及服务器在运行过程中发生任何严重错误时的相关信息。——数据库无法正常使用时&#xff0c;使用该日志 # 可以查看错误日志存放的位置 show variables like %…

虚拟机VMware安装openWrt作为旁路由

虚拟机VMware安装openWrt作为旁路由 前言&#xff1a;前提是已经成功安装了VMware Workstation Pro 一、下载openWrt系统固件 固件有很多&#xff0c;我选择的是下面这个&#xff1a; https://fw0.koolcenter.com/iStoreOS/x86_64/istoreos-22.03.5-2023121510-x86-64-squas…

SAP 配额维护 ME_UPDATE_QUOTA 解读

竟然直接insert 表 FUNCTION ME_UPDATE_QUOTA. *"---------------------------------------------------------------------- *"*"Verbuchungsfunktionsbaustein: *" *"*"Lokale Schnittstelle: *" TABLES *" XEQ…

Codeforces Pinely Round 3 (Div. 1 + Div. 2)

A.Distinct Buttons(思维) 题意&#xff1a; 你在开始时站在点 ( 0 , 0 ) (0,0) (0,0)&#xff0c;同时&#xff0c;手上有一个遥控器&#xff0c;上面有四个按钮&#xff1a; U:移动到 ( x , y 1 ) (x, y 1) (x,y1)的位置 R:移动到 ( x 1 , y ) (x 1, y) (x1,y)的位置 …

代码随想录算法训练营Day10 | 239.滑动窗口的最大值、347.前K个高频元素

LeetCode 239 滑动窗口的最大值 本题思路: 采用单调队列来完成&#xff0c;单调队列就是队列里的元素顺序&#xff0c;是单调递减/递增的情况。 那么我们应该如何维护这个单调队列呢&#xff0c;此处既然是最大值&#xff0c;那么采用的是单调递减的队列。让队列的出口处是当前…

java爬虫(jsoup)如何设置HTTP代理ip爬数据

目录 前言 什么是HTTP代理IP 使用Jsoup设置HTTP代理IP的步骤 1. 导入Jsoup依赖 2. 创建HttpProxy类 3. 设置代理服务器 4. 使用Jsoup进行爬取 结论 前言 在Java中使用Jsoup进行网络爬虫操作时&#xff0c;有时需要使用HTTP代理IP来爬取数据。本文将介绍如何使用Jsoup设…

如何给beaglebone black狗板扩容

接上一篇 beaglebone black狗板&#xff0c;交叉编译Qt5&#xff08;eglfs&#xff09;-CSDN博客 默认的分区大小已经不够了&#xff0c;需要调整 这里改成500M&#xff0c;能勉强正常&#xff0c;但是SD是32G还是有大量的剩余空间没被使用 这里可以用以下两类方法来把剩余的…

电影分线发行来势汹汹,行业新规到底利好谁?

年末的贺岁档&#xff0c;一直是各大影视公司的必争之地&#xff0c;但2023年却透露出一股不寻常的气息。 在10月份举办的第一届全国电影交易大会上&#xff0c;分线发行影片的机制被提出之后&#xff0c;贺岁档的多部影片启用了这一发行方式。 分线发行&#xff0c;简单来说…