【发布时间】:2021-11-18 23:34:17
【问题描述】:
我最近读了一本关于异步和等待模式的书,其中有一章是关于延迟等待或早期初始化的。书上说:
这允许结构提前开始异步处理,但只在需要结果时停止。
const wait = (ms) => new Promise(res => setTimeout(res, ms));
const fn = async () => {
console.log("starting");
await wait(100); // I suppose await should pause the execution
console.log("end");
}
(async () => {
const fnPromise = fn();
console.log("after"); // However after is printed brfore end
await fnPromise;
})();
如果我稍微修改一下代码
(async () => {
await fn(); // looks like the inner await only takes effect when I await an async function
console.log("after"); // after is printed after end
})();
我的意思是await 一个异步函数和直接调用它有什么区别。关于何时使用 await 或何时不使用 await 异步函数是否有任何最佳实践。 await 是否真正阻止执行,尤其是与计时器结合使用。
感谢@asynts 的snippet,我会发在这里
let samples = 100 * 1000 * 1000;
let chunk = 100000;
async function run() {
let sum = 0.0;
for(let i=0; i<samples; i++) {
sum += Math.random();
if (i % chunk === 0) {
console.log("finished chunk")
// wait for the next tick
await new Promise(res => setTimeout(res, 0));
// If await truly blocks the execution, rest of the code are all waiting?
// If await doesn't block the execution, what's the point to await here
}
}
let mean = sum / samples;
console.log("finished computation", mean);
}
setTimeout(run, 0);
【问题讨论】:
-
据我了解,
await一个异步函数会导致 innerawait阻塞执行,但这是否意味着我们需要await所有异步函数一直向上? -
我建议你,使用调试器,以查看异步函数的控制流程...
-
这里的关键是
await只暂停了包含函数的执行,而不是它之后的代码。在您点击 await` 时,该函数被挂起,它立即返回一个 promise,函数调用后的代码接收到返回的 promise 并继续执行。由调用代码对返回的 Promise 做一些有用的事情。 -
@jfriend00 所以如果你想确保外部
await之后的代码被挂起,使用外部await。或者如果你想让代码流动,不要使用外部await(这意味着忽略异步函数返回的承诺,尽管包含函数仍然会由于内部await而暂停) -
代码将在某种程度上流动。否则,您将陷入僵局,并且不会发生任何事件,甚至不会发生将完成异步操作的事件。如果这是调用者的愿望(调用者想要等待完成),您可以在外层使用
await。否则,我真的不明白你想要完成什么。您根据您的编程目标构建代码 - 它们不是适用于所有情况的通用结构。而且,您应该始终使用.catch()或在await周围的`try/catch` 处理被拒绝的承诺。
标签: javascript asynchronous async-await promise timer