2016-09-23 72 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

我首先閱讀[bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind),[apply](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

調試器在嘗試調查異步調用時可能會失敗。它可以完成,但需要一定的掌握在使用鉻開發工具。 –

回答

1

讓我們瞭解您的asyncify()函數所做的事情。

首先,請注意它立即被調用,以提供其結果作爲您的ajax()調用的第二個參數。它返回一個匿名函數。

現在,根據當匿名函數被調用時,以下兩種情況之一發生:

1),如果它立即調用,setTimeout沒有觸發呢,因此它得到它被調用的參數,並將它們與原始功能asyncify()一起包裝在一起,在您的情況下爲result。包裝使用bind()完成。然後退出,讓超時處理實際的通話。 2)如果沒有立即調用它,當它被調用時,超時已經失效,因此它可以立即用其新參數調用原始函數。這是使用apply()完成的。