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


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

    Promise.all

    PromiseAll

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

    "use strict";
    
    /**
     *
     * @author xgqfrms
     * @license MIT
     * @copyright xgqfrms
     * @created 2020-08-0
     * @modified
     *
     * @description
     * @difficulty Easy Medium Hard
     * @complexity O(n)
     * @augments
     * @example
     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
     * @solutions
     *
     */
    
    const log = console.log;
    
    const promise1 = Promise.resolve(3);
    const promise2 = 42;
    const promise3 = new Promise((resolve, reject) => {
      setTimeout(resolve, 0, 'foo');
    });
    const promise4 = new Promise((resolve, reject) => {
      reject(`promise error`);
    });
    
    const promisesOK = [promise1, promise2, promise3];
    const promisesError = [promise1, promise2, promise3, promise4];
    
    const OK = Promise.all(promisesOK).then((values) => {
      log(`promisesOK values =`, values);
    });
    
    
    const Error = Promise.all(promisesError).then((values) => {
      log(`promisesError values =`, values);
    }).catch(err => {
      log(`error =`, err)
    });
    
    setTimeout(() => {
      log(`
    OK =`, OK)
      log(`Error =`, Error)
    }, 5);
    
    /*
    
    $ node promise.all.js
    
    error = promise error
    promisesOK values = [ 3, 42, 'foo' ]
    
    OK = Promise { undefined }
    Error = Promise { undefined }
    
    */
    
    
    

    原理分析

    Promise.resolve, Promise.reject

    // Promise,不许需要用 Promise 包裹,但为了对齐也使用 Promise 包裹
    promise1 = Promise.resolve(3);
    // Promise {<fulfilled>: 3}
    
    //  ✅ 未使用 Promise 包裹
    promise1.then(v => console.log(v))
    // 3
    // Promise {<fulfilled>: undefined}
    // ✅ 使用 Promise 包裹
    Promise.resolve(promise1).then(v => console.log(v))
    // 3
    // Promise {<fulfilled>: undefined}
    
    // 非 Promise,需要用 Promise 包裹
    promise2 = 42;
    // 42
    
    // ❌ 未使用 Promise 包裹
    promise2.then(v => console.log(v))
    // Uncaught TypeError: promise2.then is not a function
    // ✅ 使用 Promise 包裹
    Promise.resolve(promise2).then(v => console.log(v))
    // 42
    // Promise {<fulfilled>: undefined}
    
    // 异常 promise
    promise4 = new Promise((resolve, reject) => {
      reject(`promise error`);
    });
    // Promise {<rejected>: "promise error"}
    
    // ❌ 未使用 catch 处理
    Promise.resolve(promise4).then(v => console.log(v))
    // Promise {<rejected>: "promise error"}
    // Uncaught (in promise) promise error Promise.then (async)
    // ✅ 使用 catch 处理
    Promise.resolve(promise4).then(v => console.log(v)).catch(err => console.log(`OK`))
    // OK
    // Promise {<fulfilled>: undefined}
    
    // Promise.resolve, Promise.reject
    

    solution

    PromiseAll

    // --unhandled-rejections=strict bug
    /*
    
    Unhandled promise rejection.
    This error originated either by throwing inside of an async function without a catch block,
    or by rejecting a promise which was not handled with .catch().
    To terminate the node process on unhandled promise rejection,
    use the CLI flag `--unhandled-rejections=strict`,
    see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
    
    */
    
    "use strict";
    
    /**
     *
     * @author xgqfrms
     * @license MIT
     * @copyright xgqfrms
     * @created 2020-08-14
     * @modified
     *
     * @description PromiseAll
     * @difficulty Easy Medium Hard
     * @complexity O(n)
     * @augments
     * @example
     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
     * @solutions
     *
     */
    
    const log = console.log;
    
    const PromiseAll = (promises = []) => {
      return new Promise((resolve, reject) => {
        let count = 0;
        const result = [];
        try {
          promises.forEach((promise) => {
            Promise.resolve(promise).then(value => {
              if(value) {
                count += 1;
                result.push(value)
              }
            }).catch(err => {
              throw new Error(err);
            });
          });
          if(count === promises.length) {
            log(`PromiseAll OK`)
            return resolve(result)
          }
        } catch (error) {
          log(`Promise Error`, error)
          throw new Error(error);
          // return reject(error);
        }
      }).catch(err => {
        log(`Promise Error`, err)
        return reject(error);
      });
    }
    
    
    

    https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode

    "use strict";
    
    /**
     *
     * @author xgqfrms
     * @license MIT
     * @copyright xgqfrms
     * @created 2020-08-14
     * @modified
     *
     * @description PromiseAll
     * @difficulty Easy Medium Hard
     * @complexity O(n)
     * @augments
     * @example
     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
     * @solutions
     *
     */
    
    const log = console.log;
    
    const PromiseAll = (promises = []) => {
      let count = 0;
      const result = [];
      return new Promise((resolve, reject) => {
        promises.forEach((promise) => {
          Promise.resolve(promise).then(value => {
            if(value) {
              result[count] = value;
              count += 1;
              // result.push(value)
            }
            if(count === promises.length) {
              // log(`PromiseAll OK`, promises)
              resolve(result)
            }
            // if(result.length === promises.length) {
            //   // log(`PromiseAll OK`, promises)
            //   resolve(result)
            // }
          }, err => {
            reject(err);
          });
        });
      });
    }
    
    // test
    const promise1 = Promise.resolve(3);
    const promise2 = new Promise((resolve, reject) => {
      setTimeout(resolve, 0, 'foo');
    });
    const promise3 = 42;
    // const promise2 = 42;
    // const promise3 = new Promise((resolve, reject) => {
    //   setTimeout(resolve, 0, 'foo');
    // });
    const promise4 = new Promise((resolve, reject) => {
      reject(`promise error`);
    });
    
    const promisesOK = [promise1, promise2, promise3];
    const promisesError = [promise1, promise2, promise3, promise4];
    
    const OK = PromiseAll(promisesOK).then((values) => {
      log(`promisesOK values =`, values);
    });
    
    // const OK = Promise.all(promisesOK).then((values) => {
    //   log(`promisesOK values =`, values);
    // });
    
    const Error = PromiseAll(promisesError).then((values) => {
      log(`promisesError values =`, values);
    }).catch(err => {
      log(`catch error =`, err)
    });
    
    // const Error = Promise.all(promisesError).then((values) => {
    //   log(`promisesError values =`, values);
    // }).catch(err => {
    //   log(`error =`, err)
    // });
    
    setTimeout(() => {
      log(`
    OK =`, OK)
      log(`Error =`, Error)
    }, 5);
    
    /*
    
    $ node promiseAll.js
    
    error = promise error
    promisesOK values = [ 3, 42, 'foo' ]
    
    OK = Promise { undefined }
    Error = Promise { undefined }
    
    */
    
    
    /*
    $ node PromiseAll.js ✅
    
    catch error = promise error
    promisesOK values = [ 3, 42, 'foo' ]
    
    OK = Promise { undefined }
    
    */
    
    
    

    PromiseAll OK ✅

    async promise order OK ✅

    
    "use strict";
    
    /**
     *
     * @author xgqfrms
     * @license MIT
     * @copyright xgqfrms
     * @created 2020-08-14
     * @modified
     *
     * @description PromiseAll
     * @difficulty Easy Medium Hard
     * @complexity O(n)
     * @augments
     * @example
     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
     * @solutions
     *
     */
    
    const log = console.log;
    
    const PromiseAll = (promises = [], debug = false) => {
      const result = [];
      return new Promise((resolve, reject) => {
        promises.forEach((promise, i) => {
          Promise.resolve(promise).then(value => {
            if(value) {
              // async promise order OK ✅
              result[i] = value;
              // async push order bug ❌
              // result.push(value)
            }
            if(result.length === promises.length) {
              if(debug) {
                log(`PromiseAll OK`, promises)
              }
              resolve(result)
            }
          }, err => {
            reject(err);
          });
        });
      });
    }
    
    // test
    const promise1 = Promise.resolve(3);
    const promise2 = new Promise((resolve, reject) => {
      setTimeout(resolve, 0, 'foo');
    });
    const promise3 = 42;
    // const promise2 = 42;
    // const promise3 = new Promise((resolve, reject) => {
    //   setTimeout(resolve, 0, 'foo');
    // });
    const promise4 = new Promise((resolve, reject) => {
      reject(`promise error`);
    });
    
    const promisesOK = [promise1, promise2, promise3];
    const promisesError = [promise1, promise2, promise3, promise4];
    
    const OK = PromiseAll(promisesOK).then((values) => {
      log(`promisesOK values =`, values);
    });
    
    // const OK = Promise.all(promisesOK).then((values) => {
    //   log(`promisesOK values =`, values);
    // });
    
    const Error = PromiseAll(promisesError).then((values) => {
      log(`promisesError values =`, values);
    }).catch(err => {
      log(`catch error =`, err)
    });
    
    // const Error = Promise.all(promisesError).then((values) => {
    //   log(`promisesError values =`, values);
    // }).catch(err => {
    //   log(`error =`, err)
    // });
    
    setTimeout(() => {
      log(`
    OK =`, OK)
      log(`Error =`, Error)
    }, 5);
    
    
    /*
    $ node PromiseAll.js ✅
    
    catch error = promise error
    promisesOK values = [ 3, 'foo', 42 ]
    
    OK = Promise { undefined }
    
    */
    
    /*
    
    $ node promise.all.js
    
    error = promise error
    promisesOK values = [ 3, 'foo', 42 ]
    
    OK = Promise { undefined }
    Error = Promise { undefined }
    
    */
    
    
    

    refs

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises

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

    Promise

    
    


    Flag Counter

    ©xgqfrms 2012-2020

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


  • 相关阅读:
    一个很好的在线测试编辑器(可以在线运行很多程序)
    基于angular的route实现单页面cnodejs
    微博
    jsonp跨域再谈
    打开IIS的快捷键
    PHPCMS笔记第二弹
    phpcms ——模板标签详细使用说明
    PHP流程管理,堪比小小程序
    PHP的简单易懂文件管理,可实现基本功能
    使用php ajax写省、市、区、三级联动
  • 原文地址:https://www.cnblogs.com/xgqfrms/p/13503592.html
Copyright © 2020-2023  润新知