2013-02-08 50 views
1

引用另一個回調中相同的對象我想要一個新的屬性添加到一個對象。看來,從這個範圍內正常工作:從的forEach

rows.forEach(function (row, i) { 
    row.foo = i; 
}); 

如果我做的console.log(行)我可以看到正確的值已添加FOO。如果我在forEach中有另一個回調,我不會再看到更改。爲什麼?

rows.forEach(function (row, i) { 
    getUserById(row.user_id, function(user) {   
    row.foo = i; 
    }); 
}); 

是的,回調get被正確激發。這裏是getUserById

function getUserById(userId, callback) { 
    connection.query('select * from t_user where id = ?', [userId], function(err, results) { 

    if (err) { 
    console.log("repo error"); 
    } else { 
    if (results.length == 0) { 
     callback(null); 
    } else { 
     callback(results[0]); 
    } 
    } 
}); 

}

+1

這應該可以,假設'getUserById'調用回調。你能發佈更多的代碼嗎? – robbrit 2013-02-08 21:44:02

+1

什麼是'getUserById'?你正在定義內部函數,但它在這裏的任何地方都沒有被調用,如果這就是你想要做的事情,那麼當邏輯相同時爲什麼你會使用替代函數定義是值得懷疑的。我的猜測是你寫回調,但你實際上從來沒有把它回調。爲什麼內部函數有一個不被使用的參數? – 2013-02-08 21:45:58

+0

也許回調被調用的時間晚於你檢查'row.foo'(比如說,在循環之後的AJAX回調)? – 2013-02-08 21:47:41

回答

0

我只能說你會看到這個問題,如果getUserById推遲調用傳遞給它的回調函數圖像。在這個假設下,你的問題是一個時間問題。

每次你打電話給getUserById並傳遞一個回調函數時,你基本上都會說「當你得到這個id的用戶時調用這個函數」,然後繼續執行你的程序的其餘部分。這意味着當調用console.log時,您的回調函數尚未被調用。相反,您必須等待所有回調完成,然後調用依賴於您在回調中設置的值的任何代碼。

的一般方法,以等待所有回調到結束是制定一個特殊的回調函數,這將委託給每個回調並跟蹤,一旦他們都被調用。

這是一個使用async庫的答案,我很喜歡這個庫(雖然有很多庫可以解決這個控制流問題)。

Idiomatic way to wait for multiple callbacks in Node.js

這裏是一個JavaScript的原料解決方案,是足夠強大,因爲不是所有的回調都是一樣的,一般情況下工作(也就是說,如果你想爲每個用戶ID的不同的回調)。

Multiple Asynchronous Callbacks - Using an array to fire function when complete