javascript - Javascript 中的任务运行器

标签 javascript asynchronous async-await promise

我有一个任务列表,只有在解决每个任务的所有依赖关系后才需要执行所有这些任务。我正在努力找出一种方法来在最佳时间完成所有任务的运行。

// Each node is a async job, illustrated by setTimeout.
// A and C can run at the same time.
// D, needs to wait for A and C to be done.
// E needs to wait for A and D to be done.

function runTasks(tasks) {
 // run tasks
}

// Sample of tasks
var tasks = {
  'a': {
    job: function (finish) {
      setTimeout(function () {
        console.log('a done');
        finish();
      }, 500);
    },
  },
  'c': {
    job: function (finish) {
      setTimeout(function () {
        console.log('c done');
        finish();
      }, 200);
    },
    dependencies: [],
  },
  'd': {
    job: function (finish) {
      setTimeout(function () {
        console.log('d done');
        finish();
      }, 100);
    },
    dependencies: ['a','c'],
  },
  'e': {
    job: function (finish) {
      setTimeout(function () {
        console.log('e done');
        finish();
      }, 200);
    },
    dependencies: ['a', 'd'],
  },
};

最佳答案

您可以启动可以启动的并行 promise 。

  1. 首先启动所有没有依赖关系的独立任务
  2. 完成独立任务后存储在 map /集合中
  3. 然后使用整套重复步骤过滤一组新任务。

const wait = (ms, task) =>
  new Promise((resolve) =>
    setTimeout(() => {
      console.log(`${task} done`);
      resolve();
    }, ms)
  );

const tasks = {
  a: {
    job: () => wait(500, "A"),
    dependencies: [],
  },
  c: {
    job: () => wait(500, "C"),
    dependencies: [],
  },
  d: {
    job: () => wait(500, "D"),
    dependencies: ["a", "c"],
  },
  e: {
    job: () => wait(500, "E"),
    dependencies: ["a", "d"],
  },
};

const run = async () => {
  const completed = new Set();
  const keys = Object.keys(tasks);
  const runTasks = async (pendingTasks) => {
    const promises = pendingTasks.map((key) => tasks[key].job());
    await Promise.all(promises);
    pendingTasks.forEach((key) => completed.add(key));
  };

  const runner = async () => {
    const pendingTasks = keys.filter((key) => {
      if (!completed.has(key)) {
        const { dependencies } = tasks[key];
        return dependencies.every((dependency) => completed.has(dependency));
      }
      return false;
    });
    if (pendingTasks.length !== 0) {
      await runTasks(pendingTasks);
      return runner();
    }
  };

  await runner();
};

run();

关于javascript - Javascript 中的任务运行器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72137667/

相关文章:

javascript - Material 组件 : change event in MDCCheckbox not working

javascript - HTML Javascript - 如何根据数字更改图像

javascript - 如何从 Firebase 的实时数据库中删除具有 UID 的用户?

javascript - 并行运行多个异步函数的安全方法?

c# - 如何同步等待取消异步任务

c# - 具有同步方法调用的异步任务

javascript - XPages execMode 部分在渲染时移除 DOM 元素

java - Servlet 3.0 测试查询中的异步属性

java - Java和Spring中的同步和异步调用

javascript - getJSON jQuery 不会填充对象