2011-12-27 96 views
1

鑑於此代碼:遍歷對象鍵/值異步

var o = { 
    k1: 'v1', 
    k2: 'v2', 
    k3: 'v3' 
}; 

var stupidf = function(k, v, callback) { 
    setTimeout(function() { 
    console.log(k + "=" + v); 
    callback(); 
    }, 2000}; 
}; 

什麼是產生輸出的最佳方式:

// after 2 seconds 
stdout: k1=v1 
// after 4 seconds 
stdout: k2=v2 
// after 6 seconds 
stdout: k3=v3 

使用數組,你會成爲一個副本,並push()它關於回調,但我真的不知道如何用對象來做到這一點。

回答

1

你假設o中的條目迭代具有有保證的順序; it does not。假設你不關心你得到什麼樣的順序出來:

function asyncIterate(o,callback,timeout){ 
    var kv=[], i=0; 
    for (var k in o) if (o.hasOwnProperty(k)) kv.push([k,o[k]); 
    var iterator = function(){ 
    callback(kv[i][0],kv[i][1]); 
    if (++i < kv.length) setTimeout(iterator,timeout); 
    } 
    setTimeout(iterator,timeout); 
} 
asyncIterate(o,function(k,v){ 
    console.log(k+'='+v); 
},2000); 

JavaScript沒有像Lua的next()功能,可以讓你找到一個給定後的下一個鍵/值對。

如果您關心條目的順序,那麼您需要將原始鍵/值對存儲在數組中,而不是對象。

+0

所以你必須創建一個數組來做到這一點?沒有創建數組沒有辦法? – 2011-12-27 17:31:46

+0

@luxun - JS對象屬性不是有序的。你可以只保留數組中的順序(而不是數值)。在這種情況下,您將擁有兩個數據結構,一個用於屬性順序的數組和一個用於保存屬性值的對象。 – 2011-12-27 17:38:43

+0

@luxun如果你可以依賴迭代的順序(一些瀏覽器保證),你可以通過存儲最後一個鍵的可怕機制,然後(在每個回調中)遍歷對象,直到你看到該鍵。但是,這不僅是可怕的低效率,它不保證按照規範工作。 – Phrogz 2011-12-27 17:48:59