JS Guide JS Guide
首页
  • JS 部分
  • HTML 部分
  • CSS 部分
  • Vue
  • React & Angular
  • 数据结构、算法、OS
  • 计网、浏览器
  • 杂项
笔试
面试
资源
资讯
  • 关于本站
  • 更新历史
  • 贡献指南
  • 文档规范
  • 常见问题
GitHub (opens new window)
首页
  • JS 部分
  • HTML 部分
  • CSS 部分
  • Vue
  • React & Angular
  • 数据结构、算法、OS
  • 计网、浏览器
  • 杂项
笔试
面试
资源
资讯
  • 关于本站
  • 更新历史
  • 贡献指南
  • 文档规范
  • 常见问题
GitHub (opens new window)
  • 面试相关说明
  • 解释代码题

  • 手撕代码题

    • 数学
    • 字符串
    • 数组
    • 手写函数实现
      • 1. 美团:手写 Promise.all
  • 个人相关

  • 面试相关
  • 手撕代码题
卡洛
2022-11-02
目录

手写函数实现

# 1. 美团:手写 Promise.all

示例:

const p1 = Promise.resolve(3);
const p2 = new Promise(resolve => {
  setTimeout(resolve, 1000, 9);
})
const p3 = Promise.resolve(5);
const p4 = 2;
const p = myPromiseAll([p1,p2,p3,p4]);
p.then(res => console.log(res));
1
2
3
4
5
6
7
8

输出:

[3, 9, 5, 2]
1

思路:

Promise.all 返回一个新的 Promise 实例,该实例在 iterable 参数内所有的 Promise 都“完成(resolved)”或参数中不包含 Promise 时回调完成(resolve);如果参数中 Promise 有一个失败(rejected),此新的 Promise 实例回调失败(reject),失败的原因是第一个失败 Promise 的结果。

因此我们首先将传入的迭代器改为数组以获得其长度,然后遍历数组,对每个元素进行 Promise.resolve 包装,然后通过 .then 和 .catch 判断每个方法的状态。

function myPromiseAll(list) {
  const arr = Array.from(list);
  const len = arr.length;
  const ans = new Array(len);
  let cnt = 0;
  return new Promise((resolve, reject) => {
    for (const i in arr) {
      const p = Promise.resolve(arr[i]);
      p.then(res => {
        ans[i] = res;
        cnt++;
        if (cnt === len) {
          resolve(ans);
        }
      }).catch(err => {
        reject(err);
      });
    }
  });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

注意

这里用 i 和 cnt 而不用 push 是因为 Promise 的执行顺序是不确定的,如果用 push 的话,ans 的顺序就会乱掉。

在 GitHub 中编辑此页 (opens new window)
上次更新于: 2022/11/3 23:25:22
数组
个人相关说明

← 数组 个人相关说明→

Theme by Vdoing | Copyright © 2022-2022 Carlo | Powered by VuePress
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式