面试官: 平时处理多个异步请求, 怎么做的,
我: 一般使用Promise.all来进行处理
面试官: 使用Promise.all, 那有没有遇见过其中某个请求异常? 遇到过,怎么处理的?
我: 我都手写过Promise,这还能难倒我? (可是当时就是脑子抽了,就是没想起来, 遇见异常是什么处理的.
这里我就开始反思, 手写Promise到底为了哈,这, 只会写, 不去思考, 活该面试忘记???.
之前手写Promise链接在这儿
需求/问题描述
- Promise.all方法中, 遇见抛出异常的方法, 是怎么处理的,
1.直接所有的结果都不能用,
2.还是异常之前的结果能用,
3.还是某些结果能用.
思考?
- 首先排除第二个答案,因为之前手写代码, 我还记得, Promise.all方法中, 使用index下标,来保证返回结果的顺序得和传入的顺序一致,所以, 异常之前的结果并不一定是在异常前就执行完成的,这个首先排除了.
- 我当时就是纠结答案1 和 答案2. 我不敢确定, 是不是在遇见异常的时候就直接reject后退出了.
- 那么这里, 我就好好抽自己, 去把之前手写的代码搬过来, 仔细研究, 然后记住!!!!!!
实际研究
// 这里上面promise基本实现和方法就不贴了, 可以查看系列一文章, 这里主要突出重点
all(promises) {
// 因为all后面也是可以进行链式调用的, 所以, 这里也需要和then一样, 返回promise的
return new Promise((resolve, reject) => {
let res = [] // 用来存储处理后返回的所有结果的数组
const length = promises.length // 传入的参数的数组长度
promise.forEach((promise, index) =>{
// 遍历数组中的每一个promise对象, 调用其then方法, 获取其中resolve或者reject的数据
+ ⚠️看这里 // ⚠️最主要的看这里!!!!! .then 返回的是resolve或者reject的数据,
//所以,遇见reject的异常也应该按照index的下标放入对应的位置.
promise.then(result => {
// 处理一个push一个
res.push(result)
// 当res结果数组长度和传入的参数长度一致时, resolve返回一下
if(res.length === promiseLength) resolve(res)
}).catch(e => reject(e))
})
})
})
}
复制代码
- 那么, 按照自己之前手写的源码,我们再写个demo, 来看看,通过研究的源码, 是否和实际输出是一样的.
const a = new Promise((resolve, reject) => setTimeout(() => resolve(new Error('发生了异常!')), 10))
const b = new Promise((resolve, reject) => setTimeout(() => resolve('111111'), 10))
const c = new Promise((resolve, reject) => setTimeout(() => resolve(new Error('发生了异常!')), 10))
const d = new Promise((resolve, reject) => setTimeout(() => resolve('111111'), 10))
Promise.all([a, b, c, d]).then(data => console.log(data)).catch(err => console.log(err))
复制代码
- 输出结果:
[
Error: 发生了异常!
at Timeout._onTimeout (/Users/cookie/Desktop/Leetcode/JS基础/Promise/ProseAll.js:1:70)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7),
'111111', // resolve的结果正常输出
Error: 发生了异常!
at Timeout._onTimeout (/Users/cookie/Desktop/Leetcode/JS基础/Promise/ProseAll.js:3:70)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7),
'111111' // resolve的结果正常输出
]
复制代码
- 结果显示, 不管是resolve, 还是reject, 最后都会按序在返回的数组中存在
总结
每次的研究和学习, 不能停下思考,这玩意儿写的时候会写,遇到问到了没有思考过的问题, 就懵了, 所以, 需要不停的思考, 去记住学习到的.
复制代码
Promise.all中, 不管遇见了resolve的data还是reject的reason, 都会按照指定的下标顺序返回.所以, 如果需要处理的请求抛了异常, 那么, 也是将这个异常在指定的位置上输出. 不会影响其他请求/异步处理返回的结果.
前端小白, 感谢您的观看, 如果感觉还可以希望给个点赞?. 感谢! 如有错误, 烦请各位大佬指出. 小弟将马上改正!
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END