持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
题外话
最近对Promise也有了一个深刻的认识,这东西就是工作只要会用就行,但是面试呢有需要你知道他怎么实现的,也就是手撕一下底层逻辑。
让会就学呗~~~~
前情回顾
前6篇的博客中国,我们对Promise的基本搭建,then方法的基本搭建以及后续一些小问题的处理逐一进行了解决。到目前为止,我们对then方法的手撕就告一段落了。接下来我们开始对Promise其他的一些方法进行讲解
正文
Promise.all()
在我们开始手撕方法之前,我们需要将这个方法的特性都了然于心,这样才能在处理的时候不漏掉知识点
了解方法
- Promise.all()接收一个数组作为参数,数组中可以是普通值也可以是promise对象
- Promise.all()返回的也是一个promise对象,是可以通过then方法进行调用的
- 如果all方法中所有promise对象状态都是成功的,那么最终返回的结果也是成功的;如果all方法中的promise对象状态有一个是失败,那么最终返回的结果就是失败。
实现
- promise接收一个数组作为参数,最终返回的也是一个数组,所以我们需要定一个一个数组用来接收最后的结果。
- all返回的也是一个promise对象
- 对接收的数组进行遍历,判断传入的参数是普通值还是promise对象,promise对象的情况下需要拿到返回值在加入到最终结果中。
方式一
Promise.all = function(array) {
//1. all方法最后返回的是一个promise对象,是可以使用then方法的
return new Promise((resolve, reject) => {
//2. 定义一个数组用来接收最后的结果
let result = []
//3.定义一个临时参数,用来判断数组传入的值里面如果存在promise对象的时候,promise对象的状态是否已经改变
let index = 0
//4. 循环传入的数组,对数组里面参数进行处理
for (let i = 0; i < array.length; i++) {
//5. 将所有参数都转换为promise对象
Promise.resolve(array[i]).then(resp => {
//6. 将每一项的结果添加到结果数组中
result[i] = resp
//7. 每向数组里添加一个结果,就讲临时变量+1
index++
//8. 判断传入的数组是否全部执行完毕,执行完毕就resolve调用
if (index === array.length) resolve(result)
}).catch(err => {
//9. 一旦发现错误就直接reject出去
reject(err)
})
}
})
}
方式一里面使用了一个Promise.resolve(),这个方法也是官方Promise提供的一个API,如果我们不使用这个方法改怎么做呢
方式二
Promise.Myall = function(array) {
//1. 同样因为all返回一个promise对象,所以这里我们直接返回一个promise
return new Promise((resolve, reject) => {
//2. 定义存储结果的数组
let result = []
//3. 定义临时变量,用来判断数组内方法是否执行
let index = 0
//4.封装一个方法将结果添加到数组里
function add(key, value) {
//4.1 以key-value的形式向数组里添加结果
result[key] = value
//4.2 每添加一个结果,就将临时变量自增1
index++
//4.3 判断数组内的参数使用都获取到结果,全部获取之后调用resolve
if (index === array.length) resolve(result)
}
//5. 循环数组
for (let i = 0; i < array.length; i++) {
//5.1 判断参数是普通值还是promise对象
if (array[i] instanceof Promise) {
//5.2 如果是promise对象,直接调用promise的then方法获取返回值,如果状态是成功就是添加到结果数组中,如果是失败就直接reject结束
array[i].then(resp => add(i, resp), error => reject(error))
} else {
//5.3 普通值直接添加进入数组
add(i, array[i])
}
}
})
}
结束
关于Promise.all()的手撕部分也结束了,相对于then方法来说,all方法就简单很多了,哈哈