2012-08-30 89 views
2

請向我解釋這是如何工作的。我是nodejs的新手,他們設置代碼的方式對我來說很難理解。使用具有函數的參數的Javascript函數?

我把我不明白的代碼分成了小片段。你可以在下面找到整個代碼。

callback(function() { 
    results.push(Array.prototype.slice.call(arguments)); 
    next(); 
}); 

我不明白上面的代碼片段。這個匿名函數似乎成爲該系列匿名函數的下一個參數?請問anon函數參數中的代碼是否會執行?

function(next) { async(1, next); } 

哪個會先執行?系列函數中的異步函數執行還是下一個參數執行?

這裏我附全碼:

function series(callbacks, last) { 
    var results = []; 
    function next() { 
    var callback = callbacks.shift(); 
    if(callback) { 
     callback(function() { 
     results.push(Array.prototype.slice.call(arguments)); 
     next(); 
     }); 
    } else { 
     last(results); 
    } 
    } 
    next(); 
} 

function async(arg, callback) { 
    var delay = Math.floor(Math.random() * 5 + 1) * 100; 
    console.log('async with \''+arg+'\', return in '+delay+' ms'); 
    setTimeout(function() { 
    callback(arg*2); 
    }, delay); 
} 

function final(results) { 
    console.log('Done', results); 
} 

series([ 
    function(next) { async(1, next); }, 
    function(next) { async(2, next); }, 
    function(next) { async(3, next); }, 
    function(next) { async(4, next); }, 
    function(next) { async(5, next); }, 
    function(next) { async(6, next); } 
], final); 

回答

3

首先,知道在JavaScript中,函數可以作爲參數傳遞給其他函數。這與傳遞從另一個函數返回的值非常不同。就拿這個簡單的例子:

function A() { 
    alert("In A"); 
} 

function B(fn) { 
    alert("In B"); 
    fn(); 
} 

B(A); // alerts "In B", then "In A". 

B(A()); // alerts "In A", then "In B", 
     // (then errors because the return value from A is undefined, 
     // and thus cannot be invoked.) 

所以,按照從開始到結束你的代碼示例,這裏是怎麼一回事呢?

  1. series是一個函數,它的功能的陣列(callbacks)和一個更函數(last)作爲參數。它首先被調用。

  2. series,定義了一個名爲next功能(不與參數的每一個命名next回調函數混淆)。函數next被調用。

  3. next之內,定義了一個名爲callback的變量。它的值是來自callbacks陣列的函數之一。存儲在callback變量中的函數被一個匿名函數調用。

  4. callback之內,async函數被調用。來自步驟3的同一匿名功能被傳遞給async。現在稱爲next,但這與series中定義的next函數沒有多大關係。

  5. async之內,一些計算完成並最終調用匿名函數(通過setTimeout)。它在async函數中被稱爲callback

  6. 在匿名函數中,一些值被壓入results數組,並調用next。這是在series中定義的next函數。

  7. 重複步驟3到6,直到調用callbacks中的所有功能,然後調用參數lastfinal)中的功能。

清澈如泥,對嗎?

+0

你好,對不起,回覆晚了。我試圖通過這段代碼來包裝我的思想。但是我還有一個問題,因爲這是代碼中最令人困惑的部分:在您提供的示例代碼中,B(A())首先發出In A,然後發送In B.因此,在我的代碼中,回調函數( ){results ..; next();})在異步之前會先執行? –

+0

因爲在步驟指南中,callback()中的anon函數在步驟6中,所以首先執行異步 –

+0

也許我不明白回調的想法。謝謝你以清晰的方式回答我的問題。我會先研究回調,然後也許我的困惑會得到回答。謝謝。 –

1

系列函數需要的功能來執行清單。每個函數都需要一個參數,這個參數需要是一個函數,一個回調函數。 series使用該回調來知道函數完成其異步工作。

這裏是一個循序漸進的步驟是什麼series做:

  1. 取的功能列表,並命名爲last
  2. 創建results數組,其中我們將存儲所有這些功能
  3. 結果一個回調
  4. 選擇的第一個項目在列表中,如果該項目不是一個功能從列表中
  5. 刪除(列表爲空):
    1. 致電lastresults陣列
    2. 停止。我們正在做
  6. 如果該項目是一個函數調用它,並將它傳遞一個新的回調,讓我們一旦該功能完成做它的異步工作,知道什麼時候它的完成
  7. 應該調用回調與任何參數數量。存儲results陣列
  8. 轉到在這些參數將3

基本上,它是一個遞歸函數,等待直到過程的每個步驟之間進行。結果將會是,在前一個完成工作之後,每個將其傳遞到它的callbacks列表中的函數將被順序調用。

不要氣餒。即使是經驗豐富的程序員,異步代碼也很難。

+0

感謝您的簡單解釋。是的,異步對我來說是非常新的。但是說實話,我的編程不是很好,所以也許這就是原因。 :) –