2014-03-02 79 views
0

我想運行一個腳本,多次執行相同的操作,但我不想在回調後寫回調。我有點用node.js初學,所以我不確定這樣做的正確方法。這裏是我的代碼如下:如何使用for循環並使用節點獲取結果?

exports.index = function (req,res) { 
    /* some code */ 
    something.execute(this, that, function(results) { 
    for (var i = 2; i <= 10; i++) { 
     var nextPage = getNextPage(i); 
    } 
    } 
} 

function getNextPage(page) { 
    something.execute(this, that, function(results) { 
    return results; 
    } 
} 

會發生什麼結果返回爲未定義。我知道這需要做一些事情,因爲節點是異步的,所以getNextPage在代碼的其餘部分完成後,但我不確定什麼是最好的解決方法。

有什麼建議嗎?謝謝!

編輯:在getNextPage中添加代碼。我幾乎爲9個頁面運行相同的代碼。看起來好像我需要弄清楚如何強制執行something.execute循環。

+0

嘗試'async'模塊 – Gntem

+1

此外,我們不能說什麼是錯的,直到你顯示你如何分配'結果'。 – rsman

+0

你需要展示更多的代碼或者解釋更多你想做的事情。如果你建議getNextPage()返回undefined,那麼你需要顯示代碼getNextPage() – wayne

回答

1

我認爲在節點中編碼這種方法/樣式的最佳概述是Mixu's Node Book Ch 7 "Control Flow"。具體示例爲「7.2.1控制流模式#1:系列 - 異步循環」和「7.2.2控制流模式#2:完全並行 - 異步並行循環」。我在這裏粘貼7.2.1給你,因爲許多計算器用戶在沒有摘錄的情況下對外部鏈接皺眉。

function async(arg, callback) { 
    console.log('do something with \''+arg+'\', return 1 sec later'); 
    setTimeout(function() { callback(arg * 2); }, 1000); 
} 
function final() { console.log('Done', results); } 

var items = [ 1, 2, 3, 4, 5, 6 ]; 
var results = []; 

items.forEach(function(item) { 
    async(item, function(result){ 
    results.push(result); 
    if(results.length == items.length) { 
     final(); 
    } 
    }) 
}) 
+0

這可能會起作用,但它在語義上完全不同:它並行地執行forEach項。回到OP的代碼,如果異步'getNextPage'取決於前一次調用的結果,那將會是一個問題。來自Async.js的'async.forEach'會更合適,IMO。它異步執行項目,但是按順序執行。 – Noseratio

+0

是的,確實如此。我的觀點是爲了編寫節點程序,你必須知道整個主題。因此,這本書的鏈接。只有很多次我想發佈一個答案,讓人們第一次碰到javascript的異步挑戰。我個人可能會使用'async.eachLimit',但我試圖發送的消息是這是你必須瞭解的核心內容。 –

+0

我明白了。我非常期待在Node和所有主流瀏覽器中全面支持JavaScript中的'yield'。這將使JavaScript中的異步編程變得輕而易舉,就像在C#中使用'async/await'一樣。 – Noseratio

1

嘗試async模塊。 async提供了許多方便的異步控制流程功能。稍後您將擁有自己的技能和信心。現在,雖然:

var async = require('async'); 

function requestHandler(req, res) { 
    var itemNumbers = ... // might depend on req; might not 

    function getItem(itemNumber, callback) { 
     // ... asynchronous function which calls back with (err, result) 
    } 

    function withResults(err, results) { 
     if (err) { 
      // handle the error 
     } else { 
      // respond normally 
     } 
    } 

    async.map(itemNumbers, async, withResults); 
} 

async.map將調用getItem每個項目一次itemNumbers。如果任何調用getItem回調出現錯誤,async.map將返回該錯誤並返回withResults。否則,async.map將返回nullerr和的回調結果數組。