【问题标题】:Javascript promise implementationJavascript 承诺实现
【发布时间】:2020-09-20 15:48:43
【问题描述】:

在 javascript 中实现下面的最佳方法是什么。

/*
  A --|
      |-- D --|
  B --|       |-- E
              |
  C ----------|

每个节点都是一个异步作业,由setTimeout 说明。

A、B、C 可以同时运行。

D,需要等待A和B完成。

E 需要等待 C 和 D 完成。

我如何实现一个接受上述节点作为参数的接口,这将负责上述实现。不确定是否可以使用 async/await 或 JavaScript 承诺以及优缺点最好实现什么。

【问题讨论】:

    标签: javascript promise async-await


    【解决方案1】:

    这是您可以使用的 Task 类。创建一个时,您需要为其提供一个名称、一个异步函数(将在任务可以启动时调用)以及该任务所依赖的其他任务实例的列表:

    class Task {
        constructor(name, asyncWork, ...neededTasks) {
            this.promise = (async () => {
                await Promise.all(neededTasks.map(task => task.promise));
                console.log("start " + name);
                await asyncWork();
                console.log("complete " + name);
            })();
        }
    }
    
    // Utility function to mimic some asynchronous work, using setTimeout:
    const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
    
    // Define the tasks. Note that they will automatically call 
    // the given function if there are no other tasks to wait for:
    let a = new Task("a", () => delay(1000));
    let b = new Task("b", () => delay(1500));
    let c = new Task("c", () => delay(2000));
    let d = new Task("d", () => delay(1000), a, b);
    let e = new Task("e", () => delay(1000), c, d);

    创建任务时,会为其创建一个承诺。它存储在其promise 属性中。这个承诺只会在以下情况下解决:

    • 为它所依赖的任务创建的“前身”承诺已解决
    • 此任务的实际异步工作已运行完成(即其返回的承诺已解决)

    这两个步骤是链接在一起的,所以在第一步的承诺得到解决之前,实际工作不会开始。

    【讨论】:

      【解决方案2】:
              /*
                A --|
                   |-- D --|
              B --|       |-- E
                         |
            C ----------|
              */
              let A = new Promise((resolve, reject) => {
                  setTimeout(() => {
                      resolve("im from A");
                  }, 0);
              });
              let B = new Promise((resolve, reject) => {
                  setTimeout(() => {
                      resolve("im from B");
                  }, 0);
              });
              let C = new Promise((resolve, reject) => {
                  setTimeout(() => {
                      resolve("im from C");
                  }, 0);
              });
              let D = new Promise((resolve, reject) => {
                  setTimeout(() => {
                      resolve("im from D");
                  }, 0);
              });
              let E = new Promise((resolve, reject) => {
                  setTimeout(() => {
                      resolve("im from E");
                  }, 0);
              });
      
              (async () => {
                  let [stringOfA, stringOfB] = await Promise.all([A, B]);
                  let [stringOfD, stringOfC] = await Promise.all([D, C]);
                  let stringOfE = await E;
                  console.log(stringOfA, stringOfB, stringOfC, stringOfD, stringOfE);
              })();
      

      【讨论】:

      • 您立即启动所有任务。
      • C 等待 A 和 B 而不是同时运行。此外,您应该解释答案的作用,而不仅仅是转储一些代码。
      猜你喜欢
      • 2014-07-09
      • 1970-01-01
      • 2014-12-29
      • 2013-02-21
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      相关资源
      最近更新 更多