• 面试会问的 Promise.all()


    Promise.all()

    来看这个的应该都在面试吧~~~😏

    Promise.all() 接收一组可迭代的 Promise 作为输入, 返回一个新的 Promise 对象, 其 resolve 回调的结果是输入的所有 Promise 的结果组成的数组.

    如果输入的参数为空的可迭代对象, 或者所有输入的 Promise 都变成已完成状态, 那么返回的 Promise 也会变成已完成状态.

    const promise1 = new Promise(resolve => {
      setTimeout(() => {
        resolve('😀');
      }, 1000);
    });
    const promise2 = Promise.resolve(2);
    const promise3 = 1;
    
    
    Promise.all([promise1, promise2, promise3])
    .then((result) => {
      console.log('result is', result);
    });
    
    // 空的可迭代对象
    Promise.all(new Set())
    .then(result => {
      console.log('new Set() result is', result);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    📕虽然 promise1 最后才变成已完成状态, 但是在返回的结果中, 它仍然是第一个. 返回结果中的位置和其完成先后没关系, 和其在传入 all() 的位置有关系

    不过一旦输入的任何 Promise 对象变成 rejected 或者输入的参数非可迭代对象(比如 null 或者 number 类型),那么返回的 Promise 立即 reject, 并且 reject 回调的结果是第一个 reject 的信息或者报错信息.

    const promise4 = new Promise(resolve => {
      setTimeout(() => {
        resolve(100);
      }, 10000);
    })
    const promise5 = Promise.reject(200);
    
    Promise.all([promise4, promise5])
    .then(result => {
      console.log('我不会执行的');
    })
    .catch(err => {
      console.log('糟糕, ', err)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    输入

    Promise.all() 接收的是可迭代对象, 而不仅仅是数组, 数组虽然是可迭代对象, 但是 set, string 等都属于可迭代对象. 因此 Promise.all('asd') 会输出什么呢?
    在这里插入图片描述

    哈哈😄, 这是因为 asd 字符串类型可迭代的. 如果我们组成可迭代对象的数据(a, s, d)不是 Promise 对象, 就会被 resolve 变成已完成状态.

    手写 Promise.all

    面试中问到最多的就是被手写 Promise.all 实现

    • 首先: 判断传入的参数是否为可迭代对象, 关于可迭代对象判断, 👉请看MDN这里👈;
    • 其次, 如果是可迭代对象, 判断是否为空, string数组 通过 length 属性判断, SetMap 通过 size 属性判断;
    • 创建两个变量, 分别使用 resolvedPromiseCountresolvedPromiseResult 用来记录已经完成的 Promise 对象的数量和结果;
    • 使用 Promise.resolve() 处理可迭代对象中每个值, 如果这个值刚好是 Promise 对象, resolve 就会原封不动地将这个对象返回; 如果这个值非 Promise 对象, 就会创建一个 resolve 这个值的 Promise 对象.
      • catch 方法中直接 reject;
      • then 方法中增加 resolvedPromiseCount 的值并将已完成的 Promise 对象的结果保存在数组 resolvedPromiseResult 的对应位置. 如果 resolvedPromiseCount 刚好等于 length 调用 resolve 返回.
      • 在这里插入图片描述
    Promise.myAll = function (iterable) {
      return new Promise((resolve, reject) => {
        if (typeof iterable[Symbol.iterator] !== 'function') {
          reject(new Error('参数必须是可迭代类型对象'));
        }
        let length = iterable.length || iterable.size;
        if (length === 0) {
          resolve([]);
        }
        let resolvedPromiseCount = 0;
        let resolvedPromiseResult = [...' '.repeat(iterable.length)]
        let i = 0;
        for (let item of iterable) {
          Promise.resolve(item)
          .then(result => {
            resolvedPromiseCount++;
            resolvedPromiseResult[i++] = result;
            if (resolvedPromiseCount === length) {
              resolve(resolvedPromiseResult);
            }
          })
          .catch(err => {
            reject(err);
          });
        }
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    谢谢你看到这里, 祝福你面试顺利😀

  • 相关阅读:
    R语言时间序列数据可视化: 使用plot函数可视化单序列时间序列数据、多序列时间序列数据并指定不同时间序列的线条类型(lty)
    12.netty中tcp粘包拆包问题及解决方法
    基于图像形态学处理的路面裂缝检测算法matlab仿真
    【github】关于分支保护
    量子城域网系列(六):关于量子信道
    MaxCompute远程连接,上传、下载数据文件操作
    Linux学习——文件IO
    提高Oracle数据库缓存命中率
    python 基准测试(cProfile \ kcachegrind \ line_profiler \ memory_profiler)
    数据分析 第三周 (numpy数组的处理 , numpy数组的运用与画图的结合)笔记
  • 原文地址:https://blog.csdn.net/broken_promise/article/details/125548720