惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recorded Future
Recorded Future
Security Archives - TechRepublic
Security Archives - TechRepublic
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Jina AI
Jina AI
I
InfoQ
D
DataBreaches.Net
人人都是产品经理
人人都是产品经理
腾讯CDC
GbyAI
GbyAI
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Microsoft Azure Blog
Microsoft Azure Blog
F
Fortinet All Blogs
博客园 - 聂微东
美团技术团队
The Register - Security
The Register - Security
Engineering at Meta
Engineering at Meta
Apple Machine Learning Research
Apple Machine Learning Research
雷峰网
雷峰网
S
Schneier on Security
量子位
A
About on SuperTechFans
H
Help Net Security
MongoDB | Blog
MongoDB | Blog
S
SegmentFault 最新的问题
Know Your Adversary
Know Your Adversary
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
Simon Willison's Weblog
Simon Willison's Weblog
PCI Perspectives
PCI Perspectives
B
Blog
K
Kaspersky official blog
V
Vulnerabilities – Threatpost
aimingoo的专栏
aimingoo的专栏
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
U
Unit 42
G
Google Developers Blog
L
LINUX DO - 最新话题
Forbes - Security
Forbes - Security
AWS News Blog
AWS News Blog
P
Palo Alto Networks Blog
Security Latest
Security Latest
爱范儿
爱范儿
Attack and Defense Labs
Attack and Defense Labs
IT之家
IT之家
L
LINUX DO - 热门话题
D
Docker
P
Proofpoint News Feed
Y
Y Combinator Blog
P
Proofpoint News Feed

ZkeqのCoding日志

年度|我的2025年度总结 从想法到落地:我是如何在两个小时的时间里做出一个人格完善站的。(支持大家随意提问情感问题) Hexo 博客搭建:一份写给新手的完全指南 Golang | 山竹记账 Go 后端版学习笔记 云声计划 | 如何使用宝塔最新版 + Vercel,来部署一个私人的影视站+音乐站 Coding | 分别用2天半和9天,我用 ClaudeCode 写出了自己的影视站和音乐站 Coding | 记一次使用 Claude Code 开发影视站&音乐站的开发历程 年度|我的2024年度总结 日常|IMYAI文本处理工具箱开源随记 项目课 | Vue.js开发印象云笔记 KubeEdge | [进阶] KubeEdge高可用环境搭建 KubeEdge | [基础] KubeEdge架构设计及其环境搭建 KubeEdge | 边缘计算基本功--云原生 KubeEdge | 多视角认识边缘计算 KubeEdge | 边缘计算,其实就在你身边 章节起手式 (转) Kubernetes | 【尚硅谷】Kubernetes(k8s)入门到实战教程丨全新升级完整版 Kubernetes | 高可用的 K8S 集群构建 [完结] Kubernetes | 证书可用时间修改 Kubernetes | Helm 及其它功能性组件
前端体系|Promise专题 - 原理以及是什么
Zkeq · 2023-09-20 · via ZkeqのCoding日志

一学期的比赛生涯在 “” 中结束了, 无论如何; 开始了新学期的学习.那么这学期主攻学业, 但是前端还是要在子任务进度下慢慢推进, 本文算是前端继续学习的一个开端~

面试面什么?

image-20230920104116918

  • 熟练使用Promise封装代码,如封装axios,Promise级联使用,掌握async、await的用法
  • 掌握Promise静态方法的使用场景、用法,Promise.all、Promise.allSettled、Promise.race、Promise.any、Promise.resolve、Promise.reject
  • 手写Promise.all、Promise.race、Promise.allSettled
  • 手写Promise.any、Promise.last、Promise.queue
  • 并发请求限制数量封装
  • 实现Promisify
  • Promise 微任务输出、async/await 微任务输出
  • 理解Promise A+规范,手写Promise

手写 Promise.all 原理

Promise.all() 静态方法接受一个 Promise 可迭代对象作为输入,并返回一个 Promise。当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝,并带有第一个被拒绝的原因。

image-20230920104826227

image-20230920104612738

手写 Promise.race 原理

Promise.race(iterable)方法返回一个promise, 一旦迭代器中的某个 promise resolve 或者 reject, 返回的 promise 就会 resolve 或reject.

Promise.race() 静态方法接受一个 promise 可迭代对象作为输入,并返回一个 Promise。这个返回的 promise 会随着第一个 promise 的敲定而敲定。

手写Promise.race

手写 Promise.allSettled 原理

Promise.allSettled() 方法返回一个在所有给定的promise都已 fuldilled 或 rejected 后的 promise, 并带有一个对象数组, 每个对象表示对应的 promise 结果.

Promise.allSettled() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个单独的 Promise。当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。

Promise.allSettled

手写 Promise.any 原理

Promise.any() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个 Promise。当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的 AggregateError 拒绝。

手写Promise.any

手写并发控制

  • 使用闭包优化并发请求结果顺序

宏任务、微任务原理

运行顺序

  • 先运行同步代码
  • 再扫描微队列依次运行并清空全部任务
  • 扫描宏队列拿出一个任务运行
  • 再扫描微队列依次运行并清空全部任务
  • 扫描宏队列拿出一个任务运行…..
  • 直到两个队列都为空

同步与放入宏队列

  • setTimeout(fn, t) 本身是同步代码,作用是创建一个定时器
  • t毫秒后把fn放入宏队列
  • new Promise(function fn(resolve, reject) { ...}) 会立即运行fn,其中**fn里也是同步代码**

放入微队列

  • 对于处于pending状态的Promise对象p,内部状态的resolve,才会触发p.then(fn)中的fn加入微队列
  • 对于处于fulfilled状态的Promise对象p, 执行p.then(fn)会立即让fn加入微队列

思路

宏任务、微任务案例1

原始代码,输出什么?

改造后,所有的函数都加个名字,便于分析

执行过程:

  1. 执行同步代码创建计时器,并立即加入到宏队列。 此时宏队列【f1】,微队列【】;
  2. 创建Promise,运行同步代码f2()。运行resolve()会触发f3加入微队列。此时宏队列【f1】,微队列【f3】。再输出2;
  3. 运行同步代码输出4。同步代码执行完毕,扫描微队列,执行全部任务,执行f3(),输出3;
  4. 拿出一个宏队列任务,执行f1(),输出1。此时队列都为空。

image-20230922095000652

案例1

宏任务、微任务案例2

输出什么?

  • 执行同步代码创建Promise对象,运行同步代码f1()。输出1,创建定时器,立即把f2加入宏队列。运行resolve(1),触发f3加入微队列。此时宏队列【f2】,微队列【f3】;
  • 创建定时器,立即把f4加入宏队列。此时宏队列【f2, f4】,微队列【f3】;
  • 运行同步代码输出5。同步代码执行完毕;
  • 扫描微队列,拿出并执行全部任务,执行f3(),输出3;
  • 拿出一个宏队列任务,执行f2(),输出2。扫描微队列为空,再扫描宏队列拿出f4执行,输出4。此时队列都为空。

image-20230922094932033

案例2

宏任务、微任务案例3

输出什么?

  1. 创建定时器,立即把f1加入宏队列。此时宏队列【f1】,微队列【】;
  2. 创建Promise对象,执行同步代码f2()。执行resolve() 触发f3加入微队列。之后输出2。此时宏队列【f1】,微队列【f3】;
  3. 运行同步代码输出6。同步代码执行完毕;
  4. 扫描微队列,拿出并执行全部任务。先执行f3(),输出3;Promise.resolve().then(f4) 立即把f4加入微队列。此时宏队列【f1】,微队列【f4】。微队列不为空,拿出f4执行,输出4。f4执行完导致当前状态fulfilled,触发f5加入微队列。拿出f5继续执行,触发f6立即加入微队列。拿出并执行f6,输出5。此时宏队列为【f1】,微队列为空
  5. 扫码宏队列,拿出运行f1,输出1。

image-20230922094902186

案例3

宏任务、微任务案例4

  1. 输出1;
  2. 创建定时器,立即把f1加入宏队列。此时宏队列【f1】,微队列【】;
  3. 输出6;
  4. 扫描微队列,为空。扫描宏队列,取出f1运行。输出2;f2立即加入微队列。此时宏队列【】,微队列【f2】。
  5. 扫描微队列,拿出并执行全部任务。执行f2(),输出3;创建计时器,立即把f3加入宏队列。f2执行完毕时导致当前promise fulfilled,触发f4加入微队列。此时宏队列【f3】,微队列【f4】。微队列不为空,继续拿出f4执行,输出5。此时宏队列【f3】,微队列【】
  6. 扫码宏队列,运行f3,输出4。结束。

image-20230922094813849

案例4

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ZkeqのCoding日志