在异步功能中调用同步功能

时间:2020-01-11 12:39:33

标签: javascript node.js asynchronous

我在理解异步功能如何在JavaScript中工作时遇到问题。让我们看下面的代码:

async () => {
      console.log(1);
      setTimeout(() => console.log(2)
        , 2000)
      console.log(3);
}

我希望异步内部的同步函数调用在执行更多代码之前应该阻塞线程。因此,我希望得到1 -> 2 -> 3而不是1 -> 3 -> 2。找不到解释为什么发生,以及如何阻止线程接收输出1 -> 2 -> 3的解释。 我正在使用带有无服务器框架的Node 12。

2 个答案:

答案 0 :(得分:1)

async本身不会等到setTimeout执行完毕。正如您从文档中看到的-在此处找到async

异步函数可以包含await表达式,该表达式会暂停异步函数的执行以等待传递的Promise的分辨率,然后恢复async函数的执行并求值为解析值。

只是构建了一个简单的示例,以查看asyncawait解决方案之间的区别,并且仅使用示例中的setTimeout

请考虑以下示例:

const getPromise = async () => {
  return new Promise((resolve) => {
    setTimeout(resolve, 3000);
  });
}

const run = async () => {
  console.log('run started');
  setTimeout(() => console.log('setTimeout finised'), 2000);
  console.log('setTimeout started');
  const promise = await getPromise();
  console.log('Promise resolved');
  console.log('run finished');
}

run();

步骤说明:

  1. 开始记录功能run的执行情况
  2. 将事件附加到setTimeout,这将在约2秒内完成
  3. 登录setTimeout开始的控制台
  4. 使用getPromise函数和await关键字创建承诺,直到resolve
  5. 在大约2秒钟内setTimeout记录已完成
  6. Promise调用resolve函数起的约3秒内
  7. run函数在resolve并记录后完成其执行。

我希望能帮助您理解代码的这一部分。

答案 1 :(得分:1)

我希望异步内部的同步函数的调用在执行更多代码之前应该阻塞线程。

可以

所以我希望得到1-> 2-> 3而不是1-> 3-> 2。

setTimeout同步的。非常明确地是为了使一个函数排队,以便在一段时间后运行。

找不到解释为什么发生,以及如何阻止线程接收输出1-> 2->3。

您本身不能。

最接近的方法是将setTimeout替换为一个循环运行的循环,直到经过一段时间为止……但这太糟糕了(它将锁定初学者的UI)。

如果您只想按顺序运行三个日志,则将setTimeout替换为可返回promise的内容,然后await进行替换(这会使异步函数进入休眠状态,并让其他任何代码继续运行直到诺言解决为止。

const timeout = function() {
  return new Promise(function(res) {
    setTimeout(() => {
      console.log(2);
      res();
    }, 2000)
  })
};


const x = async() => {
  console.log(1);
  await timeout();
  console.log(3);
}

x();

相关问题