Skip to content

Instantly share code, notes, and snippets.

@genya0407
Last active August 19, 2019 23:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save genya0407/75af968d32ef19d0480d6440f991d906 to your computer and use it in GitHub Desktop.
Save genya0407/75af968d32ef19d0480d6440f991d906 to your computer and use it in GitHub Desktop.
関数の実行がIO以外の理由で重い場合に非同期処理が全部遅延される例
// 1秒待つPromiseを返す関数を定義
const sleepOneSecond = new Promise(resolve => setTimeout(resolve, 1000))
// 無限ループしつつ、100000000回ループするごとにconsole.logする関数を定義
const looping = () => {
let a = 0;
while (true) {
a += 1;
if (a % 100000000 === 0) {
console.log('100000000 looped')
}
}
}
// 1秒待ってconsole.logする、というのを繰り返すasync関数を定義
const asyncFunc = async () => {
while (true) {
console.log('one tick')
await sleepOneSecond();
}
}
// まずasync関数を実行する
asyncFunc();
// 次に無限ループ関数を実行する
looping();
// この出力結果はどうなるだろうか?
// asyncは並行処理なので、出力は以下のようになるはずだ:
//
// one tick
// 100000000 looped
// 100000000 looped
// 100000000 looped
// one tick
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// one tick
// 100000000 looped
// ...
//
// しかし実際には以下のようになる:
//
// one tick
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
// 100000000 looped
//
// つまり、無限ループがブンブン回っている間は、asyncFuncの中のPromiseが終了していたとしても、awaitに処理が戻ってこないことがわかる。
//
// これが示唆するのは、非同期処理が裏で走っていようとも、関数がIOとかタイマー以外の理由で長い時間実行されていれば(つまりCPUをゴリゴリ使っていれば)、非同期処理の部分に処理が戻ってくることはないということだ。
// 別の言い方をすると、関数の実行が終わったタイミングで、pendingされていた非同期処理の続きが実行されるということ。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment