2017-07-11 70 views
-1

我有一個for循環,我想在每次迭代時調用一個異步函數。但我得到一個JS堆棧跟蹤錯誤。以下是我的代碼的原型。我也使用了IIFE模式,但它不起作用。在for循環中調用JavaScript異步函數

for(let i = 0; i<99999;i++){ 
    getData(i, function(err, result){ 
     if(err) return err; 
     else{ 
     console.log(result); 
     } 
    }); 
} 
function getData(number, callback){ 
    request('http://someapiurl'+number, function(err, response){ 
    if(err) callback(err, null); 
    else{ 
     callback(null, response) 
    } 
    }) 
} 
+0

如果您想在執行循環的下一次迭代之前等待getData的結果,則不能使用for循環。 –

回答

-1

您試圖在同一時間創建99999,這在大多數瀏覽器中都沒有成功。

改爲使用promise,將它們推入數組中,然後使用Promise.all讓瀏覽器處理請求,只需處理最終解析的響應。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

var p1 = Promise.resolve(3); 
var p2 = 1337; 
var p3 = new Promise((resolve, reject) => { 
    setTimeout(resolve, 100, 'foo'); 
}); 

Promise.all([p1, p2, p3]).then(values => { 
    console.log(values); // [3, 1337, "foo"] 
}); 
-1

首先,我強烈建議你調試代碼,看看用什麼發生了循環。

它很可能是循環在其內容(getData函數)執行之前完全運行,通過提取數據請求的異步行爲。如果您嘗試使用IIFE模式,您至少會將內容封裝在for循環中,以確保內容執行。實現的一個例子看起來像這樣:

for(let i = 0; i<99999;i++){ 
    (function(){ // <-- IIFE used to represent a closure. 
    getData(i, function(err, result){ 
     if(err) return err; 
     else{ 
      console.log(result); 
     } 
    }); 
    })(i); 
} 

爲了讓@mika坐在承諾給你,你可以在他們復讀的主題;只要記住承諾反模式,你會沒事的。如果你不習慣承諾,並希望在for循環中使用它,那就特別棘手。