![](/img/trans.png)
[英]What is the best practice to create an async iterator? Should I use an async generator function or rather use Symbol.asyncIterator?
[英]What is the best practice to implement a delay to for loop with async function
這是我當前使用的代碼,
function loopArrayWithAsync(array, doSthWithElement, finalCallback) {
var count = 0;
var _data = [];
var _errs = [];
for (var i = 0; i < array.length; i++) {
doSthWithElement(array[i], function (err, data) {
count++;
if (err) {
_errs.push(err);
}
if (data) {
_data.push(data);
}
if (count === data.length) {
finalCallback(_errs, _data);
}
}
}
}
然后,我將以這種方式使用該函數:
loopArrayWithAsync(array, function (element, finish) {
// element - element in the array
asyncFunc(element, function (err, result) {
if (err) {
finish(err);
} else {
finish(null, result);
}
});
}, function (errs, finalData) {
// when the for loop is finished,
// i.e. (count === data.length)
// this callback will be executed
// errs - array of err from the above callback function
// finalData - array of result from the above callback function
outerCallback(errs, finalData);
});
通過此實現,我可以遍歷帶有異步功能的數組,並在處理完數組中的所有元素后執行回調函數。
但現在我想向loopArrayWithAsync()添加延遲/間隔功能
類似於loopArrayWithAsync(array, {interval : 1000}, function (element, finish) {...
,在處理完第一個元素后,應等待1000ms,然后開始處理第二個元素,反之亦然...
我發現了另一個問題,關於在for循環中添加延遲
但是在處理異步函數時,它似乎更加復雜。
任何答案將不勝感激
=============================更新=================== ===========
這是重構后的功能
function loopArrayWithAsync(array, options, doSthWithElement, finalCallback) {
if (isFunction(options)) {
finalCallback = doSthWithElement;
doSthWithElement = options;
options = {};
}
options.interval = options.interval || 0;
options.oneByOne = options.oneByOne || false;
var _data = [];
var _errs = [];
var count = 0;
var length = array.length;
var i = 0;
(function handleIteration() {
if (i < length) {
var element = array[i];
doSthWithElement(element, function (err, data) {
if (err) {
_errs.push(err);
}
if (data) {
_data.push(data);
}
count++;
if (count === length) {
finalCallback(_errs, _data);
} else if (options.oneByOne) {
if (options.interval) {
setTimeout(handleIteration, options.interval);
} else {
process.nextTick(handleIteration);
}
}
});
i++;
if (!options.oneByOne) {
if (options.interval) {
setTimeout(handleIteration, options.interval);
} else {
process.nextTick(handleIteration);
}
}
}
}());
};
這樣我就可以以這種方式使用該函數:
loopArrayWithAsync(array, {interval : 1000}, function (element, finish) {
asyncFunc(element, function (err, result) {
if (err) {
finish(err);
} else {
anotherAsyncFunc(result, function (err, doc) {
if (err) {
finish(err);
} else {
finish(null, doc);
}
});
}
});
}, function (errs, finalData) {
outerCallback(errs, finalData);
});
要么
loopArrayWithAsync(array, {oneByOne : true}, function (element, finish) {...
逐一循環遍歷元素
loopArrayWithAsync(array, {interval : 5000, oneByOne : true}, function (element, finish) {...
逐一循環並延遲5秒來遍歷元素
可用選項 :
interval
是每次迭代之間的毫秒數,默認值: 0
如果oneByOne
為true,則該方法將僅繼續到下一個元素,直到已為當前元素調用finish
為止,默認為: false
該代碼現在適合我的情況,但是我仍將嘗試使用建議的庫使生活更輕松,謝謝
如果您發現該代碼可以進一步改進,請發表評論,期待任何建議!
您可以使用局部函數進行異步循環。 對於下一次迭代,該函數將延遲調用自身:
function loopArrayWithAsync(array, doSthWithElement, finalCallback, delay) {
var _data = [], _errs = [], i = 0;
loop();
function loop() {
doSthWithElement(array[i], function (err, data) {
if (err) {
_errs.push(err);
}
if (data) {
_data.push(data);
}
i++;
if (i === array.length) {
finalCallback(_errs, _data);
} else {
window.setTimeout(loop, delay);
}
}
}
}
要以一定間隔啟動呼叫,而不必在兩次呼叫之間有延遲,只需在不同時間使用setInterval
:
function loopArrayWithAsync(array, doSthWithElement, finalCallback, delay) {
var _data = [], _errs = [], count = 0;
for (var i = 0; i < array.length; i++) {
window.setTimeout(function() {
doSthWithElement(array[i], function (err, data) {
if (err) {
_errs.push(err);
}
if (data) {
_data.push(data);
}
count++;
if (count === array.length) {
finalCallback(_errs, _data);
}
});
}, i * delay);
}
}
如@thefourtheye所建議,您可以使用Promises
的概念,而Bluebird是一個快速而完善的庫。 Promise.settle
可讓您解決和拒絕諾言,然后檢查結果。
function loopArray(array) {
var arrayOfPromises = [];
for (var i = 0; i < array.length; i++) {
arrayOfPromises.push(doSomethingAsync(array[i]));
}
Promise.settle(arrayOfPromises).then(function (results) {
console.log("All async calls done! You can inspect the result!");
console.log(results);
});
}
function doSomethingAsync(item) {
return new Promise(function(resolve, reject){
//Do you async work here!
console.log("Entering async function call " + item);
if(item === "three"){
reject("bad value!");
}
resolve(item + " promise done!");
});
}
loopArray(["one","two","three"]);
我對以下示例做了一個JSFiddle 。 使用異步函數,promise可以為您提供很多幫助,所以我真的建議您研究一下。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.