【发布时间】:2021-12-29 21:21:22
【问题描述】:
top-level await 被 ES2022 接受,我想知道是否可以假设 await import("./path/to/module") 根本没有超时。
这是我想做的:
// src/commands/do-a.mjs
console.log("Doing a...");
await doSomethingThatTakesHours();
console.log("Done.");
// src/commands/do-b.mjs
console.log("Doing b...");
await doSomethingElseThatTakesDays();
console.log("Done.");
// src/commands/do-everything.mjs
await import("./do-a");
await import("./do-b");
这是我在运行node src/commands/do-everything.mjs 时期望看到的:
Doing a...
Done.
Doing b...
Done.
我找不到任何关于顶级等待超时的提及,但我想知道我试图做的是否是对该功能的滥用。理论上,Node.js(或 Deno)可能会在达到某个预定义的时间上限(例如 30 秒)后抛出异常。
这是我在 TLA 之前处理相同任务的方式:
// src/commands/do-a.cjs
import { autoStartCommandIfNeeded } from "@kachkaev/commands";
const doA = async () => {
console.log("Doing a...");
await doSomethingThatTakesHours();
console.log("Done.");
}
export default doA;
autoStartCommandIfNeeded(doA, __filename);
// src/commands/do-b.cjs
import { autoStartCommandIfNeeded } from "@kachkaev/commands";
const doB = async () => {
console.log("Doing b...");
await doSomethingThatTakesDays();
console.log("Done.");
}
export default doB;
autoStartCommandIfNeeded(doB, __filename);
// src/commands/do-everything.cjs
import { autoStartCommandIfNeeded } from "@kachkaev/commands";
import doA from "./do-a";
import doB from "./do-b";
const doEverything = () => {
await doA();
await doB();
}
export default doEverything;
autoStartCommandIfNeeded(doEverything, __filename);
autoStartCommandIfNeeded() 在__filename 匹配require.main?.filename 时执行函数。
【问题讨论】:
-
await没有内置任何超时,无论是顶级还是非顶级。 -
注意:我没有看到任何
try/catch或.catch()与您的任何承诺一起使用。如果其中任何一个可以拒绝,您将无法控制情况。 -
谢谢@jfriend00!你所说的受控情况是什么意思?只要我们不开始运行
do-b如果do-a失败,流程就会为我工作。我期望一个非零退出代码和一个堆栈跟踪,应该doSomethingThatTakesHours()抛出(即拒绝)。 -
是的,将堆栈跟踪输出到 stderr 是我认为不受控制的情况。您无法控制出现错误时会发生什么。它只会退出而不运行您的任何代码。一般来说,不是你将如何设计的东西。我提到了缺少错误处理,因为这是使用
await编程时非常常见的错误。但是,如果你想那样做,那就去吧。 -
其实你提的很好!当我使用
autostartCommandIfNeeded()时,我可以控制如何显示未捕获的异常,从而改进命令用户体验。这在顶级等待中会丢失,但我想我们可以通过process.on('uncaughtException', handler)修复它。例如。我们可以在每个命令中添加import "./path/to/beautify-uncaught-exceptions",这样就可以了!这些命令将不受顶级函数定义和调用的影响。如果没有 TLA 超时,这似乎是不必要的开销!
标签: node.js async-await node-modules es6-modules ecmascript-2021