[英]for loop doesn't wait for async code to finish
我有一個 for 循環,其中有一個函數調用,並且該函數還有一些異步代碼。 現在的問題是 for 循環不等待異步代碼從嵌套函數調用返回並繼續迭代。
函數aFunctionThatRunsAsync
來自一個我無法控制的庫。
下面是全部代碼。
// arr.length = 2
for (let i in arr) {
console.log(i, 'i1')
functionOne(arr[i], i, (err, res) => {
console.log(res)
})
}
function functionOne(inp, idx, callback) {
console.log(idx, 'i1')
const processor = aFunctionThatRunsAsync(inp, err => {
if (err) return callback(err);
});
processor.on('complete', data => {
console.log(data, idx, 'i3')
return callback(null, data)
});
}
問題:
代碼執行后的日志是這樣的:
0 i1 // expected
0 i2 // expected
1 i1 // unexpected, expected to have logged: data(obj) i3
1 i2 // unexpected, expected to have logged: 1 i1
最后記錄:
data(obj) 0 i3
data(obj) 1 i3 // Not always in the same order
我希望 for 循環等待異步代碼返回/記錄並以正確的順序同步運行,因此最終輸出如下所示:
0 i1
0 i2
data(obj) 0 i3
1 i1
1 i2
data(obj) 1 i3
該代碼在for-in
中沒有任何內容使其等待這些回調。
functionOne
中的代碼看起來不是基於 promise 的,因此除非您想更改該代碼,否則您需要在開始下一次迭代之前等待回調,如下所示:
process(0);
function process(i) {
if (i < arr.length) {
console.log(i, 'i1')
functionOne(arr[i], i, (err, res) => {
if (err) {
console.error(err);
// I assume you don't want to continue here
} else {
console.log(res);
process(i + 1);
}
});
}
}
或者,您可以讓functionOne
返回一個承諾:
function functionOne(inp, idx) {
return new Promise((resolve, reject) {
console.log(idx, 'i1')
const processor = aFunctionThatReturnsAPromise(inp, err => {
if (err) return reject(err);
});
processor.on('complete', data => {
console.log(data, idx, 'i3');
resolve(data);
});
})
}
然后:
let promise = Promise.resolve();
for (let i = 0; i < arr.length; ++i) {
promise = promise.then(() => (
functionOne(arr[i], i).then(res => {
console.log(res);
})
));
}
promise.catch(error => console.error(error));
請注意, for
there 里面的let
很重要。 它不能是var
,它必須在for
。 那是因為我們需要傳遞給then
的回調來關閉該循環迭代的i
,它會像上面那樣使用let
但不會使用var
。
在async
函數中使用會更容易:
// In an `async` function
try {
for (let i = 0; i < arr.length; ++i) {
console.log(await functionOne(arr[i], i));
}
} catch (error) {
console.error(error);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.