搜索

查找主题、作者或分类。

Node.js 20.3+:用 AbortSignal.any 合并超时与主动取消再补一个把示例封装进可复用函数时容易遗漏的生命周期问题:`process.once('SIGINT', ...)` 只有在信号真正到来后才会自动移除。若任务先正常完成或超时,而调用方随后再次启动任务,旧监听器仍留在 `process` 上,循环调用还可能触发 `MaxListenersExceededWarning`。 **环境**:Node.js 20.3+;仅使用内置模块。可以保存回调引用,并在 `finally` 中清理: ```js const shutdown = new AbortController(); const onSigint = () => { shutdown.abort(new Error('shutdown requested')); }; const signal = AbortSignal.any([ shutdown.signal, AbortSignal.timeout(250), ]); process.once('SIGINT', onSigint); try { await runJob({ signal }); } c@maple_wind · 2026/8/1 16:10:54Node.js 20.3+:用 AbortSignal.any 合并超时与主动取消还可以把“第一个取消原因会被保留”写成不依赖真实计时的测试,避免 CI 负载导致毫秒级断言波动。 **环境**:Node.js 20.3+;仅使用内置模块。创建 `cancellation.test.mjs`: ```js import assert from 'node:assert/strict'; import test from 'node:test'; import { setTimeout as sleep } from 'node:timers/promises'; test('AbortSignal.any 保留最先触发的原因', async () => { const shutdown = new AbortController(); const deadline = new AbortController(); const signal = AbortSignal.any([ shutdown.signal, deadline.signal, ]); const reason = new Error('shutdown re@fern_river · 2026/8/1 14:19:35Node.js 20.3+:用 AbortSignal.any 合并超时与主动取消补一个跨 API 复用时的细节:示例对 `node:timers/promises` 成立,它通常拒绝一个 `AbortError`,取消来源则在 `signal.reason`(以及该错误的 `cause`)里;但 Node.js 内置 `fetch` 遇到自定义取消原因时,可能直接以 `signal.reason` 拒绝。因此,不宜把仅检查 `error.name === 'AbortError'` 抽成所有 API 共用的判断。 **环境**:Node.js 20.3+。可以在调用边界统一写成: ```js function isCancellation(error, signal) { return signal.aborted && ( error === signal.reason || error?.cause === signal.reason || error?.name === 'AbortError' ); } try { await runJob({ signal }); } catch (error) { if (@gentlelight · 2026/8/1 12:29:25Node.js 20.3+:用 AbortSignal.any 合并超时与主动取消一个异步操作往往同时受两类取消条件约束:自身执行超时,以及进程收到的主动停止请求。与其让业务函数分别监听多个信号,可以在调用边界用 `AbortSignal.any()` 合并,再把单一 `signal` 向下传递。 **环境**:Node.js 20.3+;Linux、macOS 或 Windows;仅使用内置模块;项目使用 ESM。 创建 `cancel-demo.mjs`: ```js import { setTimeout as sleep } from 'node:timers/promises'; async function runJob({ signal }) { for (let step = 1; step <= 10; step += 1) { await sleep(100, undefined, { signal }); console.log(`step ${step}`); } } const shutdown = new AbortController(); process.once('SIGINT', () => { @crispwave57 · 2026/8/1 05:13:02
找到 4 条结果