当前位置:网站首页>手写promise.all
手写promise.all
2022-06-26 17:23:00 【丹丹的小跟班】
promise.all在日常项目里经常会碰到,今天咋们手写下promise.all这个方法,并且探究下其中的细节。
先来几个demo
const demo1 = new Promise((resolve, reject) =>{
setTimeout(() => {
resolve(1)
}, 1000)
})
const demo2 = new Promise((resolve, reject) =>{
setTimeout(() => {
resolve(2)
}, 2000)
})
const demo3 = new Promise((resolve, reject) =>{
setTimeout(() => {
resolve(3)
}, 3000)
})
const demo4 = new Promise((resolve, reject) => {
setTimeout(() =>{
reslove(4)
}, 4000)
})
开始进行
第一步我们首先应该想到promise.all是可以进行链式调用的,那么内部一定返回的是一个promise对象。
function myPromiseAll(promiseArr) {
return new Promise(resolve, reject => {
···
})
}
第二步就应该对参数进行判断。任何方法最开始都应该想到,避免后期参数类型引起的其他错误。
function myPromiseAll(promiseArr) {
return new Promise(resolve, reject => {
if(Array.isArray(promiseArr)) {
······
}else {
throw new Error('请传入数组作为参数')
}
})
}
第三步我们对数组进行遍历,这个时候应该想到会不会数组里面的元素不是一个promise对象呢?可能有人就会进行if判断,可以使用instanceof 或者万能的Object.prototype.toString.call(),但其实有更简单的办法,就是直接使用Promise.resolve()包裹元素就会自动将非promise元素变成一个promise对象。
function myPromiseAll(promiseArr) {
return new Promise(resolve, reject => {
if(Array.isArray(promiseArr)) {
const len = promiseArr.length
for(let i = 0; i < len; i ++) {
Promise.resolve(promiseArr[i]).then(res => {
······
}).catch(err => {
reject(err)
})
}
}else {
throw new Error('请传入数组作为参数')
}
})
}
第四步,根据返回的结果是一个数组我们就应该想到需要创建一个数组进行结果保存。这个时候就会出现最容易犯错的地方,那就是数组顺序,我们会发现官方的promise.all返回的数组元素里面的顺序是传入的promise数组参数的顺序。直接push可能会因为执行时间的不同从而push进结果数组的时机不同,这个时候就需要使用数组下标的方式来进行赋值,最后在判断什么时候结束判断,那就是结果数组长度等于参数的时候。
function myPromiseAll(promiseArr) {
return new Promise((resolve, reject) => {
if(Array.isArray(promiseArr)) {
const len = promiseArr.length
let resArr = []
for(let i = 0; i < len; i ++) {
Promise.resolve(promiseArr[i]).then(res => {
resArr[i] = res
if(resArr.length === len) {
resolve(resArr)
}
}).catch(err => {
reject(err)
})
}
}else {
throw new Error('请传入数组作为参数')
}
})
}
第五步,大家觉得这样就结束了?如果大家测试就会发现,上面的promise.all方法执行myPromiseAll([demo1, demo2, demo3, demo4])那是没有丝毫问题的,但是这个参数顺序是根据递增的顺序变化的,也就是说他们执行的顺序和参数顺序是一致的,如果我们置换顺序,比如demo4, demo1, demo2, demo3就会发现该数组的第一个结果竟然是空(empty),也就是说返回的结果是一个稀缺数组。那是因为第一个参数定时时间最长,所以会在最后执行,当执行到demo3的时候,i就已经等于3了,而数组使用下标进行赋值时,会改变数组的长度,尽管有时候下标的值是空(empty),所以就执行了resolve,但这是demo4并没有执行,所以会造成结果的缺失。这个时候我们就需要一个中间数字来记录我们执行了几个参数。
function myPromiseAll(promiseArr) {
return new Promise((resolve, reject) => {
if(Array.isArray(promiseArr)) {
const len = promiseArr.length
let resArr = []
let num = 0
for(let i = 0; i < len; i ++) {
Promise.resolve(promiseArr[i]).then(res => {
num ++
resArr[i] = res
if(num === len) {
resolve(resArr)
}
}).catch(err => {
reject(err)
})
}
}else {
throw new Error('请传入数组作为参数')
}
})
}
最后大功告成!
注意点总结:
- 注意参数的类型
- 注意参数数组里面的元素可以不为promise对象
- 注意成功是返回的结果顺序
边栏推荐
- 离婚协议中的几个重点
- 关于FlowUs这一款国民好笔记
- 背包问题求方案数
- Don't believe it, 98% of programmers are like this
- MySql 导出数据库中的全部表索引
- Army chat -- registration of Registration Center
- LeetCode——226. Flip binary tree (BFS)
- 直播预告|程序员进击,如何提升研发效能?6月21日晚视频号、B站同步直播,不见不散!
- Sandboxed container: container or virtual machine
- Necessary decorator mode for 3 years' work
猜你喜欢

Decentralized NFT transaction protocol will defeat opensea

Teach you to learn dapr - 9 Observability

Romance of the Three Kingdoms: responsibility chain model

Various types of gypsum PBR multi-channel mapping materials, please collect them quickly!

MySQL add column failed because there was data before, not null by default

Introduction to distributed cache / cache cluster

Niuke network: Design LRU cache structure design LFU cache structure

She said she was tired! So tired! I want to change my career

Redis OM . Net redis object mapping framework

Cache breakdown! Don't even know how to write code???
随机推荐
Ndroid development from introduction to mastery Chapter 2: view and ViewGroup
Detailed explanation of browser storage methods: the origin and difference of cookies, localstorage and sessionstorage
Record the use process of fenics
SIGIR 2022 | University of Hong Kong and others proposed the application of hypergraph comparative learning in Recommendation System
Secrets of gear contract
Convert the decimal positive integer m into the number in the forward K (2 < =k < =9) system and output it in bits
Inspirational. In one year, from Xiaobai to entering the core Department of Alibaba, his counter attack
Environment setup mongodb
牛客网:设计LRU缓存结构 设计LFU缓存结构
玩轉Linux,輕松安裝配置MySQL
Cloud native 02: Alibaba cloud cloud efficient flow pipeline
20:第三章:开发通行证服务:3:在程序中,打通redis服务器;(仅仅是打通redis服务器,不涉及具体的业务开发)
Which low code platform is more friendly to Xiaobai? Here comes the professional evaluation!
Leetcode topic [array] -268- missing numbers
Leetcode HOT100 (22--- bracket generation)
【动态规划】剑指 Offer II 091. 粉刷房子
10 cloud security best practices that enterprises need to know
Platform management background and merchant menu resource management: access control design of platform management background
Teach you to learn dapr - 4 Service invocation
Some explanations for latex CJK