javascript - 异步函数javascript不在后台运行?
问题描述
console.log("1");
console.log("2");
async function a() {
for (let i = 0; i < 1000000000; i++) {}
for (let i = 0; i < 1000000000; i++) {}
}
a().then(() => console.log("in then"));
console.log("3!");
我想要的这个输出就是这个 1 2 3!那时
但是异步函数的行为是同步的,不会让 3! 打印直到长循环执行完毕。我想如果使用 async 关键字,它会在后台运行里面的函数吗?我基本上希望 2 个长循环在后台运行。只是想了解异步和等待。谢谢。
编辑:有人能告诉我为什么这也可以同步工作吗?
console.log("2");
function lag(resolve) {
for (let i = 0; i < 1000000000; i++) {}
for (let i = 0; i < 1000000000; i++) {}
console.log("in lag");
return resolve;
}
async function a() {
// console.log("its done");
let a = await new Promise((resolve, reject) => lag(resolve));
}
a().then(() => console.log("in then"));
console.log("3!"); ```
解决方案
没有什么async
函数(或承诺)可以让任何东西在后台运行。他们不会创建新线程或类似的东西。
一个函数在第一个或async
之前是同步的。由于您的函数没有任何or ,因此它是完全同步的。await
return
await
return
Promise 的目的是观察已经异步的事情的完成,例如浏览器通过 HTTP 或计时器加载的事情。函数的目的async
是为使用 Promise 提供语法,让我们编写代码的逻辑流程,而不是编写回调函数。他们都没有做任何异步的事情,或者将事情转移到不同的线程。
如果你想在后台运行一些东西,你可以创建一个工作线程并通过消息传递在它和主线程之间交换信息。在浏览器上是web workers。在 Node.js 中,它是工作线程模块。
在您的问题和对答案的评论中,您谈到了async
函数似乎如何等待异步任务完成。事实上,函数的逻辑确实如此。但这确实是使用 Promise 的语法糖(真的,非常好的语法糖,恕我直言)。我们来看一个async
函数:
function delay(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
async function example() {
// The function starts out synchronous, so that it can
// start whatever inherently-asynchronous thing it does
// (like calling `fetch`).
console.log("[example] This is synchronous");
// When execution reaches the first `await` or `return`,
// the `async` function returns a promise. The synchronous
// part of its work is now complete.
await delay(10);
// This code runs later, when/if the promise from `delay`
// is settled.
console.log("[example] This is asynchronous, but still on the main thread");
// If you `throw` in an `async` function, it rejects the `async`
// function's promise.
if (Math.random() < 0.5) {
throw new Error("Error thrown by `example`");
}
// The "return" value of an `async` function is the fulfillment
// value of the promise the `async` function returned
return 42;
}
console.log("[top] Calling `example`...");
const promiseFromExample = example();
console.log("[top] Back from calling `example`. Waiting for its promise to settle.");
promiseFromExample
.then((value) => {
console.log(`[top] The promise from \`example\` was fulfilled with the value ${value}`);
})
.catch((reason) => {
console.log(`[top] The promise from \`example\` was rejected with the rejection reason ${reason.message}`);
});
.as-console-wrapper {
max-height: 100% !important;
}
运行几次,这样你就会看到满足和拒绝(每次运行都有 50/50 的机会)。除了主线程之外,该代码中没有任何东西在任何地方运行,只是在 中await
,逻辑example
可以等待承诺解决。来自的承诺delay
让我们观察计时器的完成,然后example
await
在继续其逻辑之前完成该完成。
关键是:
- 承诺不会使任何事情异步¹
- Promise 和
async
函数不会将任何东西移出主线程 async
函数总是返回承诺- 函数中的代码
async
同步运行,直到第一个await
或return
- 函数的承诺通过
async
函数的返回值实现,或者因函数中发生的任何错误而被拒绝
¹ 好的,有一个警告:如果您使用.then
or .catch
(or .finally
) 将回调连接到一个 Promise,即使该 Promise已经解决,该回调也将始终被异步调用。
推荐阅读
- python - 在 Python 中使用循环和数据框样式属性突出显示 Excel 列单元格
- python-3.x - 将 float64 列转换为 int64 列
- html - 为什么第二个 flexbox 容器(其中包含 SVG)向上移动?
- sql - 在 psql 命令行中连接字符串路径
- r - Azure 存储 REST Api 调用 - 标头 x-ms-version 无效
- r - 以特定格式将数据写入文本文件
- testing - 如何使用 WebDriverIO 获取可见元素
- python - 从文本文件中获取输入以实现 Caesar Cipher
- json - 如何获取 MongoDB 中的密钥?
- android - 如何在多个片段中显示保存的数据?