順番に呼び出す必要があるいくつかの関数 fn1、fn2、fn3 があるとします。もちろん、最も簡単な方法は次のとおりです。ただし、これらの関数は実行時に 1 つずつ追加され、いつ呼び出されるかわからない場合があります。現時点ではどのような関数があるのかわかりませんが、関数を追加するときに、必要に応じて配列から関数を 1 つずつ取り出して、配列に追加することができます。順番に呼び出します:
fn1(); fn2(); fn3();
このような関数には名前がなくても問題ありません。匿名関数を直接渡すことができます。テストしてみましょう:
var stack = []; // 执行其他操作,定义fn1 stack.push(fn1); // 执行其他操作,定义fn2、fn3 stack.push(fn2, fn3); // 调用的时候 stack.forEach(function(fn) { fn() });
この実装は今のところうまく機能していますが、非同期関数の呼び出しという 1 つの状況を無視しました。非同期は JavaScript では避けられないトピックですが、ここでは JavaScript の非同期に関連するさまざまな用語や概念については説明しません (有名な解説など)。次のコードが 1、3、2 を出力することがわかっている場合は、読み続けてください:
var stack = []; function fn1() { console.log('第一个调用'); } stack.push(fn1); function fn2() { console.log('第二个调用'); } stack.push(fn2, function() { console.log('第三个调用') }); stack.forEach(function(fn) { fn() }); // 按顺序输出'第一个调用'、'第二个调用'、'第三个调用'
同様の非同期関数である関数がスタック キューにある場合、実装は台無しになります。 :
console.log(1); setTimeout(function() { console.log(2); }, 0); console.log(3);
問題は明らかです。fn2 は確かに順番に呼び出されますが、setTimeout の関数 fn2Timeout() { console.log('Second call') } は (タイムアウトが に設定されていても) すぐには実行されません。 0) ; fn2 が呼び出された直後に戻り、fn3 が実行された後、実際に fn2Timeout の番になります。
どうやって解決しますか?ここで重要なのは fn2Timeout です。fn3 を呼び出す前に、実際に実行されるまで待つ必要があります:
var stack = []; function fn1() { console.log('第一个调用') }; stack.push(fn1); function fn2() { setTimeout(function fn2Timeout() { console.log('第二个调用'); }, 0); } stack.push(fn2, function() { console.log('第三个调用') }); stack.forEach(function(fn) { fn() }); // 输出'第一个调用'、'第三个调用'、'第二个调用'
一歩下がって、fn3 を実行する前に fn2Timeout が完全に実行されるのを待つ必要はなく、代わりに fn2Timeout 関数本体の最後の行で呼び出します。
function fn2() { setTimeout(function() { fn2Timeout(); fn3(); }, 0); }
これは見た目が良いですが、 fn2 の定義 fn3 はありません。この fn3 はどこから来たのでしょうか?
fn3 を fn2 で呼び出す必要があるため、stack.forEach を通じて fn3 を呼び出すことができません。そうしないと、fn3 が 2 回呼び出されることになります。
fn3 を fn2 に書き込むことはできません。代わりに、 fn2Timeout の終了時にスタック内で fn2 の次の関数を見つけて、次の関数を呼び出すだけで済みます。
function fn2() { setTimeout(function fn2Timeout() { console.log('第二个调用'); fn3(); // 注{1} }, 0); }
function fn2() { setTimeout(function fn2Timeout() { console.log('第二个调用'); next(); }, 0); }
Next は次のように使用されます:
var index = 0; function next() { var fn = stack[index]; index = index + 1; // 其实也可以用shift 把fn 拿出来 if (typeof fn === 'function') fn(); }
stack.forEach 行が削除されたので、Next は実行するスタック内の最初の関数 fn1 を見つけて、fn1 で next を呼び出します。 find out 次の関数 fn2 が実行され、次に fn2 で next が呼び出され、以下同様に続きます。
すべての関数は次に呼び出す必要があります。特定の関数に記述されていない場合、プログラムは関数を実行した後、続行するメカニズムが存在せずにすぐに終了します。
var stack = []; // 定义index 和next function fn1() { console.log('第一个调用'); next(); // stack 中每一个函数都必须调用`next` }; stack.push(fn1); function fn2() { setTimeout(function fn2Timeout() { console.log('第二个调用'); next(); // 调用`next` }, 0); } stack.push(fn2, function() { console.log('第三个调用'); next(); // 最后一个可以不调用,调用也没用。 }); next(); // 调用next,最终按顺序输出'第一个调用'、'第二个调用'、'第三个调用'。
redux と koa は、関数の途中に配置され、後続の関数を実行した後、戻って次のコードを実行します。時間があるときにまた書きます。
以上がJavaScript関数の非同期実行実装コードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。