当前位置:网站首页>手写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对象
- 注意成功是返回的结果顺序
边栏推荐
- Here comes the hero League full skin Downloader
- 一起备战蓝桥杯与CCF-CSP之大模拟炉石传说
- Prometeus 2.34.0 新特性
- 在国金证券开户怎么样?开户安全吗?
- Teach you to learn dapr - 9 Observability
- Army chat -- registration of Registration Center
- 物联网协议的王者:MQTT
- 分布式缓存/缓存集群简介
- Find out the maximum value of each column element of NxN matrix and store it in the one-dimensional array indicated by formal parameter B in order
- 用redis做用户访问数据统计HyperLogLog及Bitmap高级数据类型
猜你喜欢

14《MySQL 教程》INSERT 插入数据

SQL injection for Web Security (3)

Leetcode 1170. Frequency of occurrence of the minimum letter of the comparison string (yes, solved)

【推荐系统学习】推荐系统的技术栈

Army chat -- registration of Registration Center

【代码随想录-动态规划】T583、两个字符串的删除操作

LeetCode——226. Flip binary tree (BFS)

The king of Internet of things protocol: mqtt

In those years, interview the abused red and black trees

Concurrent thread safety
随机推荐
Cache breakdown! Don't even know how to write code???
[recommendation system learning] technology stack of recommendation system
Viewing the task arrangement ability of monorepo tool from turborepo
The function keeps the value of variable H to two decimal places and rounds the third digit
[C language] static modifies local variables
Preparing for the Blue Bridge Cup and ccf-csp
How about opening an account at Guojin securities? Is it safe?
用redis做用户访问数据统计HyperLogLog及Bitmap高级数据类型
NFT 交易市场社区所有化势不可挡
The king of Internet of things protocol: mqtt
Use FST JSON to automatically generate faster JSON serialization methods
QPushButton 样式使用示例(以及按钮setmenu添加下拉菜单的方法)
Teach you to learn dapr - 4 Service invocation
Deployment and operation of mongodb partitioned cluster
Army chat -- registration of Registration Center
你好,现在网上股票开户买股票安全吗?
Quantitative contract system development analysis case - detailed explanation of contract quantitative system development scheme
【动态规划】剑指 Offer II 091. 粉刷房子
在国金证券开户怎么样?保障安全吗?
Rich professional product lines, and Jiangling Ford Lingrui · Jijing version is listed