我在理解异步功能如何在JavaScript中工作时遇到问题。让我们看下面的代码:
async () => {
console.log(1);
setTimeout(() => console.log(2)
, 2000)
console.log(3);
}
我希望异步内部的同步函数调用在执行更多代码之前应该阻塞线程。因此,我希望得到1 -> 2 -> 3
而不是1 -> 3 -> 2
。找不到解释为什么发生,以及如何阻止线程接收输出1 -> 2 -> 3
的解释。
我正在使用带有无服务器框架的Node 12。
答案 0 :(得分:1)
async
本身不会等到setTimeout
执行完毕。正如您从文档中看到的-在此处找到async
:
异步函数可以包含await表达式,该表达式会暂停异步函数的执行以等待传递的Promise的分辨率,然后恢复
async
函数的执行并求值为解析值。
只是构建了一个简单的示例,以查看async
和await
解决方案之间的区别,并且仅使用示例中的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();
步骤说明:
run
的执行情况setTimeout
,这将在约2秒内完成setTimeout
开始的控制台getPromise
函数和await
关键字创建承诺,直到resolve
setTimeout
记录已完成Promise
调用resolve
函数起的约3秒内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();