前言
个人总结,仅供参考。
面试官问:你了解Promise吗?用的多吗?
如果你说了解,用的多,面试官基本上不会叫你手写Promise/A+规范,因为面试一般在1小时左右,手写Promise/A+会花费很长的时间;所以可能会让你手写Promise的静态方法。
Promise.all()
面试官问: 你知道Promise.all吗?
你可能回答:Promise.all接收一个数组,数组里面都是promise。
这时候,面试官反问:数组里面真的都是promise吗?
面对面试官的质疑,你可能会反应过来:里面也不全都是promise,也可以是常量。
面试官问: 它的执行情况是怎么回事呢?
你的回答:等到里面的promise全部执行完成后,才会返回结果。
面试官问: 如果里面有一个执行失败了呢?
你的回答:它会在catch里面捕获。
面试官又问:那其他的还会执行吗?
这时候你可能不会了。 答案是:会的,因为promise在实例化时,就执行了;.then()只是用来看它的结果。
既然你知道这么多promise的东西,那你就手写一下Promise.all吧。然后他会叫你补充代码...
function PromiseAll(promiseArray) {
//请在此处补全代码
}
const p1 = new Promise((res, rej) => {
setTimeout(() => {
res('p1')
}, 1000)
})
const p2 = new Promise((res, rej) => {
setTimeout(() => {
res('p2')
}, 2000)
})
const p3 = new Promise((res, rej) => {
setTimeout(() => {
res('p3')
}, 3000)
})
const test = PromiseAll([p1, p2, p3])
.then(res => console.log(res))
.catch(e => console.log(e))
console.log(test);
手写代码的坑
1.很多人不知道需要返回一个Promise对象,
function PromiseAll(promiseArray) { //返回一个Promise对象
return new Promise((resolve, reject) => {
})
}
2.最好判断一下传入的参数是否为数组,
function PromiseAll(promiseArr) { //返回一个Promise对象
return new Promise((resolve, reject) => {
if(!Array.isArray(promiseArr)) { //判断一下传入的参数是否为数组
return reject(new Error('传入的参数不是数组!'))
}
const res = []
for(let i = 0; i < promiseArr.length; i++) {
}
})
}
3.有很多人会分别判断数组里面的promise和常量, 但是里面的顺序会乱
function PromiseAll(promiseArr) { //返回一个Promise对象
return new Promise((resolve, reject) => {
if(!Array.isArray(promiseArr)) { //判断一下传入的参数是否为数组
return reject(new Error('传入的参数不是数组!'))
}
const res = []
for(let i = 0; i < promiseArr.length; i++) {
const isPromise = Object.prototype.toString.call(promiseArr[i] === '[Object Promise]')
// if(isPromise) {
// promiseArr[i].then(result => res.push(result))
// } else {
// res.push(promiseArr[i])
// }
//用promise包装
Promise.resolve(promiseArr[i]).then(value => {
res.push(value)
if (res.length === promiseArr.length) {
resolve(res)
}
})
}
})
}
优化后的答案
function PromiseAll(promiseArray) { //返回一个Promise对象
return new Promise((resolve, reject) => {
if (!Array.isArray(promiseArray)) { //传入的参数是否为数组
return reject(new Error('传入的参数不是数组!'))
}
const res = []
let counter = 0 //设置一个计数器
for (let i = 0; i < promiseArray.length; i++) {
Promise.resolve(promiseArray[i]).then(value => {
counter++ //使用计数器返回 必须使用counter
res[i] = value
if (counter === promiseArray.length) {
resolve(res)
}
}).catch(e => reject(e))
}
})
}