简体   繁体   English

如何为一组相互依赖的任务构建异步等待代码?

[英]How to construct async-await code for a set of tasks which are dependent on one another?

I am converting an async.auto flow to async await code.我正在将 async.auto 流转换为异步等待代码。 To simplify my question say I have a set of tasks and a list of dependencies of these tasks on each other how can I convert this to async await code.为了简化我的问题,说我有一组任务和这些任务相互依赖的列表,我如何将其转换为异步等待代码。 Here is an example I feel which will cover all the cases(correct me if it does not).这是我认为将涵盖所有情况的示例(如果没有,请纠正我)。

Set of tasks - a(), b(), c(), f(), d(resultOfA, resultOfB), e(resultOfB, resultOfC), g(resultOfF, resultOfE) Here to execute d we need values returned from a and b, and to execute e we need those of b and c, for g we need e and f.任务集 - a(), b(), c(), f(), d(resultOfA, resultOfB), e(resultOfB, resultOfC), g(resultOfF, resultOfE) 这里要执行 d 我们需要从 a 返回的值和 b,为了执行 e,我们需要 b 和 c,对于 g,我们需要 e 和 f。

Note that I want to complete all the tasks as early as possible请注意,我想尽快完成所有任务

Edit: Adding a sample async auto flow which I need to convert编辑:添加我需要转换的示例异步自动流

async.auto({
    a: function(callback) {
        setTimeout(() => {
            let resA = 3;
            callback(null, resA);
        }, 1000);
    },
    b: function(callback) {
        setTimeout(() => {
            let resB = 4;
            callback(null, resB);
        }, 1000);
    },
    c: function(callback) {
        setTimeout(() => {
            let resC = 5;
            callback(null, resC);
        }, 1000);
    },
    d: ['a', 'b', function(results, callback) {
        setTimeout(() => {
            //following line represents some computations which depends on resA and resB
            resD = results.a + results.b;
            callback(null, resD);
        }, 1000);
    }],
    e: ['b', 'c', function(results, callback) {
        setTimeout(() => {
            resE = results.b + results.c;
            callback(null, resE);
        }, 1000);
    }],
    f: function(callback) {
        callback(null, resF);
    },
    g: ['e', 'f', function(results, callback) {
        setTimeout(() => {
            resG = results.e + results.f;
            callback(null, resG);
        }, 1000);
    }]
}, function(err, results) {
    if (err) {
        console.log('err : ', err);
    }
    console.log('results : ', results);
});

I am aware of how to run tasks in parallel and in series from these three questions -我知道如何从这三个问题并行和串行运行任务 -

  1. way to run tasks in parallel using async/await 使用 async/await 并行运行任务的方法
  2. way to take results from the tasks running in parallel 从并行运行的任务中获取结果的方法
  3. a comparison of using Promise.all() and async await for running tasks in parallel 使用 Promise.all() 和 async await 并行运行任务的比较

Promises only complete once. Promises 只完成一次。

async function foo() {
  a = some_promise_factory();
  b = some_promise_factory();
  c = some_promise_factory();
  f = some_promise_factory();
  d = ab(a, b) // the promise resulting from ab is created
               // *before* that from bc, as it is assigned to d
  e = bc(b, c) // doesn't matter if promise b is used again
  g = ef(e, f) // an 'await promise_e' in ef won't resolve
               // until e is resolved, which won't resolve until
               // bc resolves, which won't resolve until
               // both 'await promise_b' and 'await promise_c' ..

  // can await any promise in an async function..
  return await g;
}

Then inside ab , bc , ef , for example.然后在abbcef ,例如。 Having the await inside is different than ab(await a, await b) ;里面的 await 与ab(await a, await b) if the await is applied to the arguments first, the call won't be made until those are resolved.如果先将 await 应用于参数,则在解决这些参数之前不会进行调用。 Pick the form that works best for the given task.选择最适合给定任务的表单。

async function ab (promise_a, promise_b) {
  return (await promise_a) + (await promise_b) + 1;
}

async function bc (promise_b, promise_c) {
  return (await promise_b) + (await promise_c) * 2;
}

async function ef (promise_e, promise_f) {
  return (await promise_e) + (await promise_f) / 3;
}

While an async function implicitly returns a promise, a normal function returning a Promise is also sufficient.虽然async函数隐式地返回一个 Promise,但一个普通的函数返回一个 Promise 也足够了。

While the above, without forcing resolving in arguments, is "the most parallel" (fsvo "parallel" 1 , depending on promise sources ), it's not always needed and will be slower in the cases when it's trivially not needed.虽然上述内容在强制解析参数的情况下是“最并行的”(fsvo "parallel" 1取决于承诺来源),但并不总是需要它,并且在几乎不需要的情况下会更慢。 If a call doesn't involve IO, or related continuations, it can probably avoid being async or involving promises.如果调用不涉及 IO 或相关的延续,它可能可以避免async或涉及承诺。

1 It's probably better to consider such concurrent rather than parallel . 1考虑这样的concurrent而不是parallel可能更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM