【问题标题】:Asynchronous Javascript: Run two functions at the same time异步 Javascript:同时运行两个函数
【发布时间】:2023-02-05 20:49:27
【问题描述】:

我正在努力提高我对异步 JavaScript 的理解。为此,我制作了一个可能需要很长时间才能完成的函数,这将完全阻止任何其他代码的执行。

为了测试这一点,函数计数。第一次调用从 1 到 10000000。第二次调用从 10 到 100。

代码

async function LongTask(from, to) {
    //Count up
    let myNum = from
    

    console.log(`counting from ${myNum} to ${to}`)

    while (myNum != to) {
        //console.log(`myNum: ${myNum}`);
        await myNum++;

    }
    console.log(`counting from ${from} to ${to} done!`);
}

//2 functions that take some time to finish
LongTask(1, 10000000);
LongTask(10, 100);

//Do unrelated stuff
console.log("Hello World!");

输出

counting from 1 to 10000000
counting from 10 to 100
Hello World!
counting from 10 to 100 done!
counting from 1 to 10000000 done!

我设法得到它,因为它更快,所以 10 到 100 将首先完成。但是,我在第 10 行 await myNum++; 收到一条警告说'await' 对此表达式的类型没有影响。删除 await 关键字会导致代码阻塞,因此函数的第 10 到 100 次调用将不得不等待更长的时间,不相关的 1 到 10000000 次调用在被调用之前完成。

我是否误解了异步 JavaScript 的工作原理,是否有更好的方法来确保 10 到 100 的调用首先完成?

【问题讨论】:

  • await 仅在与 Promises 一起使用时才有意义。你真的不能等待其他任何东西,它只会产生价值并继续。
  • 认为您可以使用带有异步等待的 Promise.all 执行多个异步等待,试试吧
  • 计数对于这种类型的插图不是很好,因为它们基本上都是瞬时的。使用 sleep function 以确保一个花费的时间比另一个长。 jsfiddle

标签: javascript asynchronous async-await


【解决方案1】:

您只能等待您的函数(以及每个 async 函数)返回的 Promise。您必须在某个时候 await 这两个承诺,以确保程序不会在承诺解决之前退出。

您可以使用 Promise.all() 等待多个承诺。我改变了你的例子来等待一个预定义的时间跨度来说明它是如何工作的,因为我然后确切地知道我期望一个函数何时完成。

(async() => {
  async function LongTask(ms) {
    console.log(`starting task that will take ${ms} milliseconds`)
    await waitFor(ms);
    console.log(`ended task that took ${ms} milliseconds`);
  }

  async function waitFor(ms) {
    return new Promise((resolve, reject) => setTimeout(() => resolve(), ms))
  };

  //2 functions that take some time to finish
  const start = new Date();
  console.log(`Calling both functions at ${start}`)
  const countToSmallNumberPromise = LongTask(4000);
  const countToLargeNumberPromise = LongTask(1000);

  //Do unrelated stuff
  console.log("Hello World!");
  // await both promises to make sure they finish before the program finishes
  await Promise.all([countToLargeNumberPromise, countToSmallNumberPromise])
  const end = new Date();
  // program will end after approx. 4 seconds (at least 4 seconds), so both functions actually run in parallel 
  // (that's actually not correct, there is no real parallelism here, as Node or your browser are single-threaded)
  // To be correct: they run concurrently, not in parallel.
  console.log(`Ending program at ${end}. Program ran for ${end - start} milliseconds`);
})();

仅供参考:Difference between concurrent and in parallel

【讨论】:

  • 你的 Promise.all 在这里没有做任何事情,因为你没有捕获它的返回并且 log 调用包含在 LongTask 中。 (删除它,输出将相同)
  • 是的,你是对的,马上就注意到了 :D 我已经更正了程序
猜你喜欢
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多