2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Promise.raceのタイムアウトで処理が止まらない理由:待機と中断をNode.jsで実測

2
Posted at

Promise.race でタイムアウトを作っても、競わせた処理は自動では止まりません。待つ側がエラーを受け取ったあとに、本来の処理の完了ログが出る例を実測しました。

Claude Code のコードでも、待機と中断を分けて読みます。前回は結果の選び方、今回は処理の継続です。

2026年11月9日、macOS 27.2・Node.js v24.22.1でタイマーを実測しました。ブラウザ・HTTP通信・サーバー側の中断は未検証です。

タイムアウト後にも完了する

race.mjs に保存し node race.mjs で実行します。タイマーの数値はミリ秒の指定値で、実行時刻の保証ではありません。

import { setTimeout as sleep } from 'node:timers/promises';

const work = sleep(60).then(() => console.log('work: completed'));

try {
  await Promise.race([
    work,
    sleep(10).then(() => { throw new Error('timeout'); }),
  ]);
} catch (error) {
  console.log('race:', error.message);
}

await work;

出力です。

race: timeout
work: completed

catch のあとにも完了しました。最後の await work は観測用です。

race は最初の決着を採用し、入力を止めません。今回の処理は sleep(60) の呼び出しで開始します。

中断に対応する処理へsignalを渡す

node:timers/promises の setTimeout は AbortSignal を受け取れます。別の abort.mjs として実行します。

import { setTimeout as sleep } from 'node:timers/promises';

const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10);

try {
  await sleep(60, undefined, { signal: controller.signal });
  console.log('abortable work: completed');
} catch (error) {
  console.log('abortable work:', error.name);
} finally {
  clearTimeout(timeout);
}

await sleep(80);
console.log('check: end');

出力です。

abortable work: AbortError
check: end

中断に対応する sleep へsignalを渡すと、成功時の完了ログは出ませんでした。末尾の待機は後からログが出ないか見る実験用です。

finally では通知タイマーを片付けます。処理が先に終わった場合にも、あとから中断通知が発火するのを避けます。

中断への対応が必要

処理する側がsignalを受け取り、中断に対応する必要があります。

signalを渡さず、別のcontrollerで abort() を呼んでも結び付きません。

HTTP通信でサーバー側の変更も取り消せるかは未検証です。変更済みの可能性があり、再送の可否は別に判断します。

生成されたコードでは、次を確認します。

  • Promise.race の catch 以降にも、本来の処理が完了する経路があるか。
  • 中断したい処理がsignalを受け取れるか。実際に引数として渡しているか。
  • 成功・失敗・中断のあとに、不要になったタイマーを片付けているか。

参照


未経験者向けの体験版を公開しています

※ 中上級者には易しすぎる内容なので、初心者の知り合いへの紹介や社内研修の参考としてどうぞ。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?