node.js - 如何使用 async forEach 依次迭代两个数组
问题描述
我有两个数组。我想使用 async.foreach 迭代数组。但是当我这样做时,只有第二个数组被执行。如何执行两者。下面是我的代码:
var _sizesArray1 = [_2000px, _1400px]
var _sizesArray2 = [_800px, _400px, _200px, _100px]
async.forEachOf(_sizesArray1, function(value, key, callback) {
async.waterfall([
function download(next){
//code
},
function convert(response, next) {
//code
},
function process(response, next) {
gm(response).command('convert')
.resize(_sizesArray[key].width,_sizesArray[key].width)
.gravity('Center')
.extent(_sizesArray[key].width,_sizesArray[key].width)
.quality('20')
.toBuffer(
'JPG', function(err,
buffer) {
if (err) {
next(err);
} else {
console.timeEnd(
"processImage array1"
);
next(null,
buffer,
key);
}
});
}
});
async.forEachOf(_sizesArray2, function(value, key, callback) {
async.waterfall([
function download1(next){
//code
},
function convert2(response, next) {
//code
},
function process3(response, next) {
//code
}
});
在我的代码中,只有 array2 被调用。为什么不执行第一个。我的代码中是否有任何错误。有人可以帮助解决这个问题。
解决方案
这个简单的技术怎么样:
var allSizes = _sizesArray1.concat(_sizesArray2);
async.foreach(allSizes, function(value, key, next) {
// do whatever you like with each item in the concatenated arrays
// once you are done move to the next item
next()
})
根据评论更新
版本 1,基于回调(欢迎回调地狱):
function asyncIterate(array, onEach, onDone) {
async.forEach(array, (val, index, onNext) => {
onEach(val, key, function onDecoratedNext() {
// tell the async.forEach it's ready for the next item
onNext();
// but if it got to the end,
// then mark the completion of the whole iteration
if (index === array.length) {
onDone();
}
});
});
}
并像这样实现它:
function doAsyncStuffWithEachItem(val, index, cb) {
// do async stuff with each item
// make sure to mark the completion of the async operation
cb();
}
asyncIterate(
_sizesArray1,
doAsyncStuffWithEachItem,
function onDone() {
// once the 1st iteration finished, time to move to the 2nd array
asyncIterate(
_sizesArray2,
doAsyncStuffWithEachItem,
function onDone2() {
// great we are done
// What if we have _sizesArray3, 4, 5 ... ?
// Well, we can continue to nest more callback here
// but in that way we'll soon end up with callback hell
// and that's a big NoNo
}
)
}
);
版本 2,基于 Promises:
为了避免回调地狱,幸运的是我们可以使用 Promises。这样的事情应该这样做:
const promisifiedAsyncIterate = (array, onEach) =>
new Promise((resolve) => {
asyncIterate(array, onEach, resolve);
});
并像这样使用它:
promisifiedAsyncIterate(_sizeArray1, doAsyncStuffWithEachItem)
.then(() => promisifiedAsyncIterate(_sizeArray2, doAsyncStuffWithEachItem))
.then(() => promisifiedAsyncIterate(_sizeArray3, doAsyncStuffWithEachItem))
.then(() => promisifiedAsyncIterate(_sizeArray4, doAsyncStuffWithEachItem))
它可以被进一步抽象和清理,甚至可以完全动态化——比如你有一个 sizeArrays 数组,你可以传递给你的函数,但我认为现在这已经足够了 :)。希望能帮助到你。
推荐阅读
- excel - 循环遍历特定列中的行,然后执行 if 语句
- jquery - 如何从 MVC5 中的 jquery ajax 调用中获取部分视图和 JSON 数据?
- javascript - 如何使用 Angular 在我的组件中使用 datePipe?
- xamarin - Urhosharp Material.FromImage 无法处理一些 jpg 文件
- sql - 语法错误,在 Access 中,无法使用 SQL 创建表单
- qt - Qt 条件文件包含在 .pro 中
- java - 如何从 acroform 获取字体颜色?
- python - Scrapy:使用 Spider 中的自定义目录保存在 JSON 文件中
- php - 想使用 laravel 将产品项目显示到购物车中
- shell - 如何使用 grep 将 stdout 拆分为 stdout 和 stderr?