This不是一個遞歸問題,它是一個「異步問題」。你的問題是NodeJS異步訪問memcached,而你的程序風格代碼不能。所以,你需要以不同的方式思考問題。
function getMemcacheData(key, data)
{
DB.get(key, function(err, result)
{
if (err) return false;
data[ key ] = result;
})
}
var oData = {};
for (var x = startX; x <= endX; x++)
{
for (var y = startY; y <= endY; y++)
{
var key = x + "_" + y;
getMemcacheData(key, oData);
}
}
這將工作,但 - 你有另一個問題,然後。你無法知道你的MemcacheD數據何時被加載到oData
中,你只能坐下來等待和猜測。有辦法解決這個問題。但我最喜歡的方式是使用名爲async
的庫。
隨着異步,你可以這樣做:
var syncStack = [],
oData = {};
for (var x = startX; x <= endX; x++)
{
for (var y = startY; y <= endY; y++)
{
(function(key)
{
syncStack.push(function(callback)
{
DB.get(key, function(err, result)
{
/** If you don't care about data not being loaded
you do this: */
if (!err)
{
data[ key ] = result;
}
callback();
/** If you do care, and you need to terminate if
you don't get all your data, do this: */
if (err)
{
callback(err);
return false;
}
data[ key ] = result;
callback();
})
});
})(x + "_" + y);
}
}
async.parallel(syncStack, function(error)
{
//this is where you know that all of your memcached keys have been fetched.
//do whatever you want here.
//if you chose to use the 2nd method in the fetch call, which does
//"callback(error)" error here will be whatever you passed as that
//err argument
});
這段代碼實際上做的是建立一個函數數組,其中的每一個要求的特定鍵的Db.get
方法,並將結果添加到oData
變量。
創建函數數組後,我們使用async
庫的parallel
方法,該方法接收一組函數並將它們全部並行地調用。這意味着您的代碼會將一堆請求發送到memcached以便一次性獲取您的數據。當每個功能完成時,它會調用callback
函數,該函數告訴async
庫,請求已完成。當它們全部完成時,async
將調用您作爲調用parallel
方法的第二個參數提供的回調閉包。當這個方法被調用時,你要麼知道A.出了什麼問題,並且你有錯誤可以從它恢復,B.所有的請求都完成了,你可能有或沒有你請求的所有數據(過期或過期的密鑰請求, 管他呢)。從那裏,你可以做任何你想做的事,知道你已經完成了所有你需要的鑰匙。
我希望這會有所幫助。
在你的第一個代碼你排隊_all_ Memcached的請求一次,然後得到的結果,而不是連載他們一個一次。這可能是排隊請求的一個_lot_。那是故意的嗎? – Alnitak
@Alnitak在這兩個片段中,我排隊所有的請求,並立即發射(幾乎)。只是它與OP代碼的最接近版本而言是有意的。例如,有更好的方法來處理它,以提高效率 - 例如,MemcacheD可以讓您通過一個請求爲大量密鑰進行多次獲取。這種方法在這裏更加適合,並且對於大量的密鑰更快速/更高效。我只是選擇儘可能保持答案儘可能接近OP的當前流量 - 所以他可以很容易地理解它(笑) –
我明白了,謝謝。問題是:在'data [key] = result;'鍵總是最後一個鍵,這就成了一個參考問題,我也用我的「家釀」思路得到了:\也許我應該使用memcached而不是memcache插件,因爲它支持多件:) –