質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.36%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

タイムアウト

タイムアウトはイベント発生から完了までに掛かる経過時間に対する一定の待ち時間を指します。また、特定の時間が経過された場合に発生するイベントを指すこともあります。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

1回答

2233閲覧

Promise.race でタイムアウトを設定し、指定時間後に処理を終了させる方法

DEADBEEF

総合スコア8

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

タイムアウト

タイムアウトはイベント発生から完了までに掛かる経過時間に対する一定の待ち時間を指します。また、特定の時間が経過された場合に発生するイベントを指すこともあります。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

0クリップ

投稿2021/11/11 07:41

編集2021/11/11 07:43

背景・目的

現在、Node.jsを使用したタイムアウトの実装を考えています。

私の考えている「タイムアウト処理」とは、
『ある関数の処理が、指定時間内に終了しなかった場合、その処理を強制的にリターン(or キル)させる』
というものです。
(例:sh/bash の timeoutコマンド)

しかし検索をかけても、Node.jsには私の考えている「タイムアウト処理」が見当たらなく、
代わりに「Promise.race(A, B)」を使用する例が多く書かれておりました。

該当のソースコード

Nodejs

1async function timeout(msec) { 2 return new Promise((_, reject) => setTimeout(reject, msec)) 3} 4 5// 時間の掛かる処理(円周率計算)を記述しています。 6// 負荷処理のサンプルとして記述しており、中身に関しては特に意味はありません。 7function calc_pi() { 8 console.log( 'start' ) 9 const begin = Date.now() // 実行時間を計測 10 11 var l = 0.0 12 for ( let n=1; n<1e10; ) // l = 1/1 - 1/3 + 1/5 - 1/7 + ... 1/1e10 (8s以内に終了) 13 { 14 l += 1.0 / n 15 n += 2 16 l -= 1.0 / n 17 n += 2 18 } 19 console.log( l * 4 ) 20 console.log( `${ ( Date.now() - begin ) / 1000 } sec.` ) // 実行時間を表示 21} 22 23async function main(timeout_ms) { 24 return Promise.race([calc_pi(), timeout(timeout_ms)]) 25} 26 27// 引数は "㎳" で指定 28main(1000);

解決したい事象

上記スクリプトは、
『1秒(1000ms)以内に処理が終了しない場合は、処理を終了(タイムアウト)させる』

を考えて作成したのですが、作成した上記スクリプトでは、1秒経過後も処理し続け、最終的に完了させるまで処理を実行してしまいます。

JavaScript初心者であり、非同期処理も慣れていない為か、もしかすると初歩ミスを犯している可能性と考えております。

どなたか、ご教授の程、どうかお願い致します。

補足情報(FW/ツールのバージョンなど)

OS:Windows 10 Pro
Node.js:v14.18.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

Node.jsは基本的にシングルスレッドで動作します。ふつうのforループで書いた長い長い処理は、同期的に実行されますので、Promiseによって非同期処理できる対象ではありません。

投稿2021/11/11 07:47

maisumakun

総合スコア145950

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/11/11 07:50

同期処理だけで長時間かかっているものをタイムアウトさせるには、「ループ内にタイムアウト処理を作り込む」、あるいは「Worker(Node.js 12ではすんなり使える)に処理を振る」などの措置が必要です。
DEADBEEF

2021/11/11 07:56

早速のご回答、ありがとうございます。 for文が「同期的」に実行され、Promiseの「非同期」処理には対応できていない事は理解できました。 それでは、for文を記述していない、下記のスクリプトでも同様の事象(1秒で処理が終了欲しいが、処理が終了せず、処理が終了するまで終わらない)が発生するのは、どこに不足分があるのか、伺ってもよろしいでしょうか? [Node.js]======================================== // 1s const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 1000, 'one'); }); // 20s const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 20000, 'two'); }); // 「promise1 」が終了したら、すぐに終わってほしい。 Promise.race([promise1, promise2]).then((value) => { console.log(value); }); ==============================================
maisumakun

2021/11/11 07:59

Promise.raceは、「どちらかの状態が動けば結果を返す」Promiseを返す関数です。与えたPromiseを強制終了させる効果はありません。
DEADBEEF

2021/11/11 08:10

ありがとうございます。 >> Promise.raceは、「どちらかの状態が動けば結果を返す」Promiseを返す関数です。与えたPromiseを強制終了させる効果はありません。 上記内容は、全く勘違いしていた内容であり、これで合点がいきました。 タイムアウトを実装するにおいて、まずは「Worker」調べ、実装を試みてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問