Javascriptasynchronous调用链接

给定一个包含typesA和B的对象的数组,其中B可以通过asynchronous调用转换为一组Atypes对象,这将是将数组转换为全A对象数组的最佳方式(将每个B对象在一组相应的A对象中)并在Bs被转换时执行callback?

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 } 

那么,在transformBtoList所有callback函数返回结果之后,您需要执行最后的callback。 有多种方法可以做到这一点:

  1. 计算你已经过去了多lesscallback,当他们回电时递减,并且当计数器再次达到零时,你知道你已经完成了。

    但是,这很麻烦,有些库可以帮助你:

  2. 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)) } } 
  3. 承诺(有许多实现是一种优越的方法,它们可能会更复杂一些,但是有很好的属性,并且会导致简洁的语法。

     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); } 

这是一个完整的工作示例与asynchronous:

 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'}]