したがって、松葉杖を開発しました。これにより、実行後にコールバックを開始する非同期関数をより明確に呼び出すことができます。 解決策は長い間存在している可能性がありますが、残念ながら、そのような解決策は見つかりませんでした。
UPD
![画像](https://habrastorage.org/getpro/habr/post_images/1f7/a26/d5b/1f7a26d5bddd25a702eea2940fc6a3b3.jpg)
以下は私のソリューションです。これは、 非同期モジュールのこの機能の類似物であり、コメントに示されている他の同様のソリューションの束です。 特にコメントして下さったすべての方、そして独裁者のおかげです。
/ UPD
サイトの架空のパーサーの例(先頭から取得され、エラーが発生する可能性があります)の例を考えてみましょう。解析後、データベースにデータを入力し、入力後にコードを呼び出します。
var html = ''; request.on('response', function (response) { response.on('data', function (chunk) { html = html + chunk; }); response.on('end', function() { //- parse(html, function(data){ //- , addToDatabase(data, function() { doSomething(); }) }); }); });
多くのネストされたコールバック-ぶんぶんうという音はありません。
var html = ''; var responceOnEnd = function() { parse(html, parsed); } var parsed = function(data){ addToDatabase(data, addedToDatabase) } var addedToDatabase = function() { doSomething(); } request.on('response', function (response) { response.on('data', function (chunk) { html = html + chunk; }); response.on('end', responceOnEnd); });
しかし、混同される可能性のあるいくつかの追加変数があります。
これを行うことをお勧めします:
wait(function(runNext){ request.on('response', runNext); }).wait(function(runNext, response){ response.on('data', function (chunk) { html = html + chunk; }); response.on('end', function() { runNext(html); }); }).wait(function(runNext, html){ parse(html, runNext); }).wait(function(runNext, data){ addToDatabase(data, runNext); }).wait(function(){ doSomething(); })
面白い? さらに進みましょう。
機能待機。
//first — , wait = function(first){ // return new (function(){ var self = this; var callback = function(){ var args; if(self.deferred.length) { /* */ args = [].slice.call(arguments); /* - */ args.unshift(callback); // self.deferred[0].apply(self, args); // self.deferred.shift(); } } this.deferred = []; // this.wait = function(run){ // this.deferred.push(run); // this return self; } first(callback); // }); }
コードとコメントが透明であるかどうかはわかりません。数秒自分で考えなければなりません:)
明確にするために、いくつかのシーケンシャルアニメーションを作成しました。
wait(function(runNext){ log(' '); $('#div1').animate({ top: 30 }, 1000, function(){ // - runNext(1,2); }); }).wait(function(runNext, a, b){ // log(' , a='+a+' b='+b ); $('#div2').animate({ top: 50 }, 1000, runNext); }).wait(function(runNext){ log(' '); setTimeout(function(){ log(' ') runNext(); }, 2000); }).wait(function(runNext){ log(' '); $('#div3').animate({ left: 50 }, 1000, runNext); }).wait(function(runNext){ log(' '); $('#div1').animate({ top: 0, left: 45 }, 1000, runNext); }).wait(function(){ log(''); });
JSFidleで例を実行する
どのように機能しますか?
まず、wait関数が呼び出されます。その引数は、次のコードバッチを呼び出すコールバック(この例ではrunNextとして定義されています)として機能する1つの引数ですぐに始まる別の関数です。 現在のステップで受け取った引数の一部を渡すことができるコールバックが実行された後、waitメソッドに渡される次の関数が呼び出されます。この関数の最初の引数はスクリプトの次の部分を呼び出すコールバックで、残りは前のステップでコールバックに渡される引数です。 などなど。
実際には、それだけです。
PS
記事をお気に入りに追加した人の数から判断すると、この投稿には価値があるので、たぶんそれを隠さないでしょう。