JavaScript 是单线程的,并且与 UI 在同一个线程中运行。所以所有的 JavaScript 代码都会阻塞 UI。正如其他人提到的,网络工作者可用于在其他线程中运行代码,但它们有局限性。
异步函数和常规函数之间的区别在于它们返回一个承诺。使用回调,您可以延迟代码的执行,该代码处理函数调用的结果,从而允许 UI 完成一些工作。以下三个示例具有相同的效果:
async function foo() {
console.log("hi");
return 1;
}
foo().then(result => console.log(result))
console.log("lo");
function foo() {
console.log("hi");
return 1;
}
Promise.resolve(foo()).then(result => console.log(result))
console.log("lo");
function foo() {
console.log("hi");
return 1;
}
const result = foo();
setTimeout(() => console.log(result));
console.log("lo");
在所有三种情况下,控制台都会记录 hi, lo, 1。在打印 1 之前,UI 可以处理用户输入或绘制更新。在前两种情况下最后打印的原因 1 是 promise 的回调没有立即执行。
await
允许您在没有回调的情况下做到这一点:
async function foo() {
console.log("hi");
return 1;
}
async function bar() {
const result = await foo();
console.log(result);
}
bar();
console.log("lo");
这也将打印 hi, lo, 1。就像 promise 的回调一样,后面的代码await
永远不会立即执行。