Promise.myAll = function (promises) { return new Promise((resolve, reject) => { const values = [] promises.forEach((promise) => { promise.then( (res) => { values.push(res) if (values.length === promises.length) { resolve(values) } }, (err) => { reject(err) } ) }) }) }
然后面试官就发现了我面试的漏洞,然后就问我如何保证每个promise返回结果的顺序。
我说我们加入的顺序就是最后返回结果的顺序啊。他又给我举了一个promise的场景,然后我理解了他说的意思。
就是我们的promise数组,例如[p1, p2, p3]
。p2执行的时间可能比p3长,那么如何确保p1, p2, p3 resolve的结果保证顺序。因为我们刚刚使用的是push方法,所以会出现问题。
然后面试官让我现场再想想。其实当时脑子一片空白。哎说真的,我自认为自己对微任务宏任务这一块还是了解的比较多的。但是我当时阙文面试官,我们在处理每一个promise.then的时候是不是按照顺序的。
其实我们可以通过循环promise数组的下标来进行添加resolve的值的。然后引入一个计算器来计算成功结果的个数。
Promise.myAll = function (promises) { // return new Promise((resolve, reject) => { // const values = [] // promises.forEach(async (promise, i) => { // // promise.then( // // (res) => { // // values.push(res) // 这里需要使用count去累加。 // // if (values.length === promises.length) { // // resolve(values) // // } // // }, // // (err) => { // // reject(err) // // } // // ) return new Promise((resolve, reject) => { const values = [] let count = 0 promises.forEach((promise, i) => { Promise.resolve(promise).then( // 还有就是对于传入的非promise的包裹。 (res) => { count++ // values.push(res) // 这里需要使用下标添加。 values[i] = res // if (values.length === promises.length) { // 这里也不能通过数组长度判断,因为后面的promise状态改变后直接就添加到values数组中,然后长度也为promises.length。但是前面的promise还没返回值。所以需要一个变量来控制。 // resolve(values) // } if (count === promises.length) { resolve(values) } }, (err) => { reject(err) } ) }) }) }