2016-09-23 8 views
2

誰かがこのコードの周りを頭にお手伝いしてくれますか?私はこの場合最初に実行されるコードは自分で決めることはできません。/これは常にコンソールに1を出力することを保証しますが、理由は分かりません。また、持つライン「orig_fn.bind.applyは...」私にとっては非常に混乱して:/関数を常に非同期にする

function asyncify(fn) { 
    var orig_fn = fn, 
     intv = setTimeout(function(){ 
      intv = null; 
      if (fn) fn(); 
     }, 0) 
    ; 

    fn = null; 

    return function() { 
     // firing too quickly, before `intv` timer has fired to 
     // indicate async turn has passed? 
     if (intv) { 
      fn = orig_fn.bind.apply(
       orig_fn, 
       // add the wrapper's `this` to the `bind(..)` 
       // call parameters, as well as currying any 
       // passed in parameters 
       [this].concat([].slice.call(arguments)) 
      ); 
     } 
     // already async 
     else { 
      // invoke original function 
      orig_fn.apply(this, arguments); 
     } 
    }; 
} 

function result(data) { 
    console.log(a); 
} 

var a = 0; 

ajax("..pre-cached-url..", asyncify(result)); 
a++; 
+0

[バインド](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)、[適用](https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply)、[setTimeout](https://developer.mozilla.org/en-US/docs/Web/API)/WindowTimers/setTimeout)など。 –

+0

また、デバッガを取得してコードをステップ実行します。それは「どのコードが最初に実行されるのか」を見る最も簡単な方法です。 –

+0

デバッガは非同期呼び出しを調査しようとすると惨めに失敗するでしょう。これを行うことはできますが、chrome開発ツールの使用にはある程度の熟練が必要です。 –

答えて

1

のは、あなたのasyncify()機能が何をするのかを理解しましょう。

まず、呼び出しがajax()呼び出しの2番目の引数としてその結果を提供するように呼び出されることに注意してください。それは無名関数を返します。

の2つのいずれかが起こる今、その無名関数が呼び出されたときに応じて、:

1)それはすぐに呼ばれていた場合、setTimeoutはまだトリガされませんでしたので、それはそれはと呼ばれた引数を取得し、あなたのケースではresultである元の関数asyncify()が呼び出されてそれらを一緒にラップします。ラッピングはbind()を使用して行われます。それから、タイムアウトが実際の呼び出しを処理するように、終了します。

2)すぐに呼び出されないと、呼び出されたときにタイムアウトが既に終了しているため、新しいパラメータで元の関数をすぐに呼び出すことができます。これはapply()を使用して行われます。

関連する問題