面试官:Promise.all有实现过吗

393 阅读2分钟

以前研究过promise相关的api的手写。要了解的请访问这里

我一听,这我太熟悉了啊。自认为promise研究的还是挺深入的啊。结果...

大致把实现逻辑说了一遍。

    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)
        }
      )
    })
  })
}

其实通过这么一个简单的提问来看,自己知识对于一些知识的了解还只是了解。考虑问题不全面,还是得认认真真,虚虚心心的学习啊。

加油啊,xdm。

虽然二面过了。但是hr面可能答得不是很理想啊。希望能过吧。

image.png