顶级等待是否有超时?

Does top-level await have a timeout?

随着 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.

则执行函数

据我所知,async-await默认是没有超时的。例如,有 await-timeout 包,它添加了超时行为。示例:

import Timeout from 'await-timeout';
 
const timer = new Timeout();
try {
  await Promise.race([
    fetch('https://example.com'),
    timer.set(1000, 'Timeout!')
  ]);
} finally {
  timer.clear();
}

摘自文档:https://www.npmjs.com/package/await-timeout

如您所见,实例化了一个 Timeout,其 set 方法定义了超时和超时消息。

回答:不,await 没有顶级超时。

此功能实际上在 Deno 中用于网络服务器,例如:

import { serve } from "https://deno.land/std@0.103.0/http/server.ts";

const server = serve({ port: 8080 });
console.log(`HTTP webserver running.  Access it at:  http://localhost:8080/`);

console.log("A");

for await (const request of server) {
  let bodyContent = "Your user-agent is:\n\n";
  bodyContent += request.headers.get("user-agent") || "Unknown";

  request.respond({ status: 200, body: bodyContent });
}

console.log("B");

在此示例中,“A”在控制台中打印,而“B”直到网络服务器关闭(不会自动发生)才显示。