2017-07-08 5 views
1

setTimeoutがJavaScriptで正確に何をするのか誤解していると思います。私はこのスクリプトを持っている:私は起こることを期待する何setTimeoutがNode.jsで長すぎるのを待つ

function recursiveFibonacci(n) { 
    if (n === 0) { 
     return 1; 
    } else if (n === 1) { 
     return 1; 
    } else { 
     return recursiveFibonacci(n-1) + recursiveFibonacci(n-2); 
    } 
} 

setTimeout(() => {console.log("one second");}, 1000); 

console.log(recursiveFibonacci(42)); 

はrecursiveFibonacciは、フィボナッチ数列における第43回値に離れて一気飲みを開始するということです。これは私のコンピュータで約4秒かかります。だから、仕事の1秒後の評価が中断されるだろうし、コンソールがログになります。

one second 

をしてから約3秒後にログインします。

433494437 

代わりに何が起こること、という4秒後で、コンソールログ:

433494437 
one second 

これはなぜですか? setTimeoutを動作させるにはどうすればよいですか? JavaScriptインタプリタが実際にはsetTimeoutで中断されているのではなく、が他のジョブを終了した場合はとなります。与えられた関数を呼び出す前に所定の時間が経過するまで待ちますか?

編集:

私は、関連する概念を理解するため、このツールは非常に有用であることが判明:

Loupe

+1

'setTimeout'は、他の実行コードと並行して(ほぼ)一定時間内にコマンドを実行する関数です。 '$ .delay()'のような遅延にもっと興味があるようです。そして、はい、通訳は中断されません。 – Mikael

+0

@Mikael、 '$'はノードに定義されていません。それを使用するには何をインポートしますか? – SeanLetendre

+0

jQuery。 JavaScriptの文脈では '$'は通常jQueryを意味します。がんばろう。 – Mikael

答えて

6

Javascriptがイベント駆動型とシングルスレッドです。 reverseFibonacci()関数は同期関数なので、完了するまで他の関数の実行を許可しません。

したがって、タイマーが起動してタイマーコールバックがinternal nodejsイベントキューに入れられても、reverseFibonacci()機能が完了するまで、JSインタープリタはイベントキュー内の次のイベントに到達できません。

setTimeout()現在実行中のJavascriptを中断しません。代わりに、イベントキューにイベントを入れ、現在実行中のJavascriptが完了すると、JSインタプリタは次のイベントをイベントキューから取り出して実行します。

だから、あなたのシナリオでのイベントの順序はこれです:

  1. 今から1秒のタイマーイベントのスケジュールを設定します。
  2. 実行を開始するreverseFibonacci()
  3. 1秒後にタイマーが起動し、イベントがnodejsイベントキューに挿入されます。
  4. 4秒後にreverseFibonacci(42)の実行が終了しました。
  5. 現在実行中のJSが終了したので、JSインタプリタは次のイベントをイベントキューから取り出して処理し、最終的にタイマーコールバックが呼び出されます。

タイマーは自分のスケジュールされた時間後できるだけ早くsetTimeout()実行とスケジュールが、JavaScriptインタプリタは他のコードを実行しているビジー状態の場合、彼らはそのコードを中断しないでください。タイマーシステムはイベントをイベントキューに入れ、その他のコードが完了すると、Javascriptインタプリタはイベントキューから次のイベントを取り出して実行します(タイマーコールバックが呼び出されます)。

1

あなたの関数が同期仕事をしていませんので、それはです。

node event loopの性質は非同期です。関数の実行が終了するか、非同期のものが実行されます - nextTickが呼び出されます。そして、おそらく最初の項目はあなたが設定されたTimout機能になります。ここで

は意図非同期チャンクとの例だと、あなたが期待するように動作します:Node.jsの中

function sleep(ms) { 
    return new Promise((resolve, reject) => { 
    setTimeout(resolve, ms); 
    }); 
} 

async function recursiveFibonacci(n) { 
    await sleep(10); 
    if (n === 0) { 
     return 1; 
    } else if (n === 1) { 
     return 1; 
    } else { 
     return await recursiveFibonacci(n-1) + await recursiveFibonacci(n-2); 
    } 
} 

setTimeout(() => {console.log("one second");}, 1000); 

recursiveFibonacci(25).then(console.log); 
関連する問題