两个嵌套 async.each 调用
Two nested async.each calls
我有以下方法:
mergeAinBbyAttr: function(a, b, attr1, attr2, val, cb) {
var result = [];
async.each(a, function(itemA, cb1) {
async.each(b, function(itemB, cb2) {
if (itemA[attr1] == itemB[attr1]) {
itemB[attr2] = val;
}
result.push(itemB);
cb2(null, result);
},
function(e, result) {
sails.log('[result]', result);
cb1(e, result);
});
},
function(e, result) {
cb(e, result);
});
}
我基本上想将一个对象数组 (A) 与另一个对象数组 (B) 进行比较,return 一个更新的数组 (C) 与 B 中的每个项目进行比较,但使用 A 中的属性进行更新.
以上[结果]return未定义。
谢谢
首先,这都是同步代码,所以你不需要异步模块,你只需要常规的循环结构。但假设您需要异步。
使用 async.map
代替 async.each
,为了更简洁:
mergeAinBbyAttr: function(a, b, attr1, attr2, val, cb) {
async.map(a, function(itemA, cb) {
async.map(b, function(itemB, cb) {
if (itemA[attr1] === itemB[attr1]) {
itemB[attr2] = val;
}
cb(null, itemB);
},cb);
},cb);
}
您不需要为 cb 变量命名不同的名称,因为它们具有不同的作用域。
如果你想在这个例程的末尾使用扁平数组,我建议使用来自 lodash 或下划线的 _.flatten
或 _.flattenDeep
。
注意这个:
function(e, result) {
cb(e, result);
});
可以简化为:
cb
=================================
使用同步方法执行此操作:
mergeByAttr: function(a, b, attr1, attr2, val) {
return a.map(function(itemA){
return b.map(function(itemB){
if (itemA[attr1] === itemB[attr1]) {
itemB[attr2] = val;
}
return itemB;
});
});
}
如您所见,无论哪种方式,您都会得到嵌套数组,它与异步模块无关,而是代码的性质。
性能更高但功能较少的方式:
mergeByAttr: function(a, b, attr1, attr2, val) {
a.forEach(function(itemA){
b.forEach(function(itemB){
if (itemA[attr1] === itemB[attr1]) {
itemB[attr2] = val;
}
return itemB;
});
});
}
好吧,我看到上面的答案对你有帮助,只是我想强调关于你的错误的一件事:
[结果] returns 未定义。
是因为根据文档,可选函数只有 1 个参数,而您试图获取 2 个参数:function(e, result)
我有以下方法:
mergeAinBbyAttr: function(a, b, attr1, attr2, val, cb) {
var result = [];
async.each(a, function(itemA, cb1) {
async.each(b, function(itemB, cb2) {
if (itemA[attr1] == itemB[attr1]) {
itemB[attr2] = val;
}
result.push(itemB);
cb2(null, result);
},
function(e, result) {
sails.log('[result]', result);
cb1(e, result);
});
},
function(e, result) {
cb(e, result);
});
}
我基本上想将一个对象数组 (A) 与另一个对象数组 (B) 进行比较,return 一个更新的数组 (C) 与 B 中的每个项目进行比较,但使用 A 中的属性进行更新.
以上[结果]return未定义。
谢谢
首先,这都是同步代码,所以你不需要异步模块,你只需要常规的循环结构。但假设您需要异步。
使用 async.map
代替 async.each
,为了更简洁:
mergeAinBbyAttr: function(a, b, attr1, attr2, val, cb) {
async.map(a, function(itemA, cb) {
async.map(b, function(itemB, cb) {
if (itemA[attr1] === itemB[attr1]) {
itemB[attr2] = val;
}
cb(null, itemB);
},cb);
},cb);
}
您不需要为 cb 变量命名不同的名称,因为它们具有不同的作用域。
如果你想在这个例程的末尾使用扁平数组,我建议使用来自 lodash 或下划线的 _.flatten
或 _.flattenDeep
。
注意这个:
function(e, result) {
cb(e, result);
});
可以简化为:
cb
=================================
使用同步方法执行此操作:
mergeByAttr: function(a, b, attr1, attr2, val) {
return a.map(function(itemA){
return b.map(function(itemB){
if (itemA[attr1] === itemB[attr1]) {
itemB[attr2] = val;
}
return itemB;
});
});
}
如您所见,无论哪种方式,您都会得到嵌套数组,它与异步模块无关,而是代码的性质。
性能更高但功能较少的方式:
mergeByAttr: function(a, b, attr1, attr2, val) {
a.forEach(function(itemA){
b.forEach(function(itemB){
if (itemA[attr1] === itemB[attr1]) {
itemB[attr2] = val;
}
return itemB;
});
});
}
好吧,我看到上面的答案对你有帮助,只是我想强调关于你的错误的一件事:
[结果] returns 未定义。
是因为根据文档,可选函数只有 1 个参数,而您试图获取 2 个参数:function(e, result)