xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

重学 MDN Web API 文档: Promise All In One

重学 MDN Web API 文档: Promise All In One

image

Promise

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("foo");
  }, 300);
});

// 错误用法 ❌
myPromise.then((res, err) => {
   console.log(`res =`, res);
   console.log(`err =`, err);
});
// res = foo
// err = undefined
// Promise {<fulfilled>: undefined}

const myPromise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("bug");
  }, 0);
});

// 错误用法 ❌
myPromise2.then((res, err) => {
   console.log(`res =`, res);
   console.log(`err =`, err);
});
// ❌ Promise {<rejected>: 'bug'}
// Uncaught (in promise) bug

myPromise2.then((res) => {
   console.log(`res =`, res);
 }, (err) => {
   console.log(`err =`, err);
});
// err = bug
// Promise {<fulfilled>: undefined}

image

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#chained_promises

demos

js 值类型 不可变性

使用 js 实现一个 Promise.all 类似方法 PromiseAll


"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2023-02-22
 * @modified
 *
 * @description 使用 js 实现一个 `Promise.all` 类似方法 `PromiseAll`
 * @description
 * @difficulty Medium
 * @ime_complexity O(n)
 * @space_complexity O(n)
 * @augments
 * @example
 * @link https://www.cnblogs.com/xgqfrms/p/13503592.html
 * @link https://www.cnblogs.com/xgqfrms/p/17145402.html
 * @solutions
 *
 * @best_solutions
 *
 */

// export {};

const log = console.log;


// 附加条件
// 1. 保证 Promise 返回值与传入参数数组中的顺序一致
// js get return value of setTimeout ???

const PromiseAll = (promises) => {
  // 实现
  return new Promise((resolve, reject) => {
    let arr:any[] = [];
    let num = 0;
    for (let i = 0; i < promises.length; i++) {
      // 使用 index 保证 Promise 返回值与传入参数数组中的顺序一致
      promises[i].then(res => {
        // 按序返回
        // console.log(`res:${i} =`, res);
        arr[i] = res;
        num += 1;
        // ✅ number 值类型, 具有不可变性
        // console.log(`✅ num =`, num);
        if(num === promises.length) {
          // then 里面是异步代码,待 promise 微任务执行完后,然后再执行
          return resolve(arr);
        }
        // ❌ 数组 引用类型 bug,地址引用,动态变化
        // console.log(`❌ arr.length, promises.length =`, arr.length, promises.length);
        // if(arr.length === promises.length) {
        //   return resolve(arr);
        // }
      }, err => {
        // console.log(`err:${i} =`, err);
        reject(err);
      });
    }
    // 这里是同步代码,promise 微任务还没执行完成就返回了 ❌
    // resolve(arr);
  });
}


const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('ok 1');
  }, 400);
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('ok 2');
  }, 300);
});

const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('ok 3');
  }, 200);
});

const p4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('ok 4');
  }, 100);
});

const p5 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('error 5');
  }, 500);
});

const all = PromiseAll([p1, p2, p3, p4]);
all.then(res => {
  console.log(`✅ res =`, res);
}, err => {
  console.log(`❌ err =`, err);
});

const bug = PromiseAll([p1, p2, p3, p4, p5]);
bug.then(res => {
  console.log(`✅ res =`, res);
}, err => {
  console.log(`❌ err =`, err);
});


// $ npx ts-node ./promise.all.ts

/*

✅ res = [ 'ok 1', 'ok 2', 'ok 3', 'ok 4' ]
❌ err = error 5

*/


image

(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!

refs

如何使用 js 实现一个 Promise.all 方法 PromiseAll All In One

https://www.cnblogs.com/xgqfrms/p/13503592.html

模拟 Promise.all & Promise.allSettled

https://www.cnblogs.com/xgqfrms/p/14016391.html

Promise.allSettled & Promise.all & Promise.race & Promise.any All In One

https://www.cnblogs.com/xgqfrms/p/13414614.html



©xgqfrms 2012-2021

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2023-02-22 18:07  xgqfrms  阅读(34)  评论(7编辑  收藏  举报