给定一个包含A和B类型对象的数组,其中B可以通过异步调用转换为一组A类型对象,这将是将数组转换为全A对象数组的最佳方法(转换一组相应的A对象中的每个B对象并在转换Bs时执行回调?
list = [A, B, A, B, A, A, B, A];
function transform (B, callback) {
//transform B type object into A type objects array [A, A, A].....
callback([A, A, A]);
}
transformBObjectsIntoAObjects(list, callback) {
// ?????????
callback(list); // this should only be A type objects
}
答案 0 :(得分:2)
好吧,在transformBtoList
的所有回调都返回结果后,你需要执行最后的回调。有多种方法可以做到:
计算你已经过去的回调数量,并在他们回电时递减,你知道当计数器再次达到零时你就完成了。
然而,这很麻烦,有些图书馆可以帮助您:
async.js众所周知且易于使用:
function transform(B, callback) { … }
function transformBObjectsIntoAObjects(list, callback) {
async.map(list, function(X, cb) {
if (X is B)
transform(X, cb)
else
cb([X])
}, function(results) {
callback(concat(results))
}
}
Promises(有many implementations是一种更好的方法。它们可能要复杂一点,但是它们具有非常好的属性并且会产生简洁明了的语法。在你的情况下,它会是
function transform(B) { // no callback!
// async:
resolve([A, A, A]); // see docs of your promise library
return promise; // for exact reference
}
function transformBObjectsIntoAObjects(list) {
return Promise.all(list.map(function(X) {
return (X is B) ? transform(X) : Promise.resolve([X]);
})).then(concat);
}
答案 1 :(得分:1)
以下是使用async的完整工作示例:
var async = require("async")
function A (id) {
this.id = 'A' + id;
}
function B (id) {
this.id = 'B' + id;
}
var list = [new A(1), new B(2), new A(3), new B(4)];
function transformBObjectsIntoAObjects (b, callback) {
var ar = [], count = Math.random() * 5;
for (var i = 1; i <= count; i++)
ar.push(new A(b.id + "_" + i))
return callback(null, ar);
}
async.map(list, function(arItem, cb) {
return (arItem.constructor === B) ? transformBObjectsIntoAObjects(arItem, cb) : cb(null, arItem)
}, function (err, arResult) {
var flatAr = [].concat.apply([], arResult);
console.log(flatAr);
}
)
一个这样的结果(B部分是随机生成的)看起来像:
[{id:'A1'}, {id:'AB2_1'}, {id:'AB2_2'}, {id:'A3'}, {id:'AB4_1'}]