【问题标题】:Make asynchronous function calls and use async/await进行异步函数调用并使用 async/await
【发布时间】:2021-01-01 23:33:53
【问题描述】:

我正在尝试弄清楚如何进行异步函数调用并使用 async/await。这在分解长流程时可能很有用。我能想到的最佳解决方案写在下面。有更好的方法吗?

NB 这是一个人为的例子。问题不在于如何处理长时间运行的进程。这是关于进行“异步函数调用并使用 [of] async/await”。

async function callAsync(fn) {
    let args = Array.prototype.slice.call(arguments, 1);
    return new Promise((resolve, reject) => {
        setImmediate(() => {
            try {
                resolve(fn(...args))
            }
            catch (e) {
                reject(e);
            }
        })
    })
}

async function longProcessPart1(x) {
    return x;
}

async function longProcessPart2(x) {
    return x;
}

(async function fn() {

    try {
        let result = await callAsync(longProcessPart1, 1);
        result = await callAsync(longProcessPart2, result);  // Use the result of longProcessPart1 in longProcessPart2.
        console.log(result);
    }
    catch (e) {
        console.log(e);
    }
}())

【问题讨论】:

  • 确实是这样。请注意,如果它们不能并行完成,那么长流程,如果一个依赖于前一个的结果,那么使它们异步没有任何好处,所以你只需一个一个地等待它们。
  • @MadaManu setImmediate 是否允许其他进程可能在每个 longProcessN 之间运行?如果要对此类进程进行排队,我正在尝试允许其他进程在 longProcess1 和 longProcess2 之间运行。
  • 我不太喜欢“可能”这个词。何时何地运行的是序列。如果要允许进程在其他进程之间运行,那么就会失去执行流程。这个想法是,如果有其他进程不依赖于它们的结果来启动另一个进程,那么它们可以被执行。想象 3 个进程 a、b、c(都返回相应的值)。如果计算 c 依赖于 a 但不依赖于 b。 A&B 过程可以并行发生,但 C 只能在 A 之后发生。
  • @MadaManu 我制作 longProcess1 和 longProcess2 异步函数的一个原因是它们也可能等待异步进程(这是实际用例中的场景)。
  • @MadaManu 在第一次 setImmediate 之后,如果 HTTP 服务器(例如,本机 http 模块)正在运行,是否可以将回调添加到轮询队列中?并且,添加到 Poll 队列的回调是否可以在 longProcess1 和 longProcess2 之间执行?

标签: node.js async-await es6-promise


【解决方案1】:

这可能是一种方式。但是我建议使用节点的承诺。但是,如果您的 longProcesses 是同步的,您只需要这样做,否则您可以直接等待它们(我可以看到 longProcesses 是异步的)

 const {promisify} = require('util');
 const delay = promisify(setImmediate);

(async function fn() {

    try {
        await delay();
        let result = longProcessPart1(1);
        await delay();
        result = longProcessPart2(result);  // Use the result of longProcessPart1 in longProcessPart2.
        console.log(result);
    }
    catch (e) {
        console.log(e);
    }
}())

编辑:这是一个工作示例:

const longProcessPart1 = () => {
  let i = 0;
  for (i = 0; i < 1000000; i++) {}
  console.log('longProcessPart1 done returning', i);
  return i;
};

const longProcessPart2 = i => {
  for (; i < 1000000000; i++) {}
  console.log('longProcessPart2 done returning', i);
  return i;
};

(async function fn() {
  try {
    await delay();
    let result = longProcessPart1(1);
    await delay();
    result = longProcessPart2(result); // Use the result of longProcessPart1 in longProcessPart2.
    console.log(result);
  } catch (e) {
    console.log(e);
  }
})();

如果您的 longProcesses 是 CPU 密集型的,那么我建议使用 worker threads。在当前的 LTS 中是稳定的。

【讨论】:

  • @Abhishek chandel API 声明 promisify,“采用常见的错误优先回调样式的函数”。但是,我想不出为什么这不起作用的任何原因。可以吗?
  • @stackhatter 我错过了一个括号。查看我发布的工作代码。
猜你喜欢
  • 2017-12-17
  • 2016-12-04
  • 2020-01-31
  • 2013-04-11
  • 2019-07-24
  • 1970-01-01
相关资源
最近更新 更多