2014-09-22 5 views
1

Учитывая массив, содержащий объекты типа A и B, где B можно преобразовать в набор объектов типа A, посредством асинхронного вызова, который был бы лучшим способом преобразования массива во все Массив объектов (преобразует каждый объект B в набор соответствующих объектов A) и выполняет обратный вызов при преобразовании Bs?Цепь асинхронных вызовов Javascript

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

вы используете библиотеки, как асинхронная или когда делать? – closure

+0

@closure уверен, решение также может использовать async. – maephisto

ответ

2

Ну, вы должны выполнить свои заключительные обратные вызовы после всех обратных вызовов из transformBtoList возвратившихся результата. Есть несколько способов сделать это:

  1. сосчитать, сколько обратных вызовов вы миновали и декремента, когда они перезвонить, и вы знаете, что вы закончили, когда счетчик снова достигнет нуля.

    Однако, это громоздко, и есть библиотеки, которые помогут вам в этом:

  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. 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

Вот полный рабочий пример с асинхронным:

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: 'А1'}, { ID: 'AB2_1'}, { идентификатор: 'AB2_2'}, { идентификатор: 'A3'}, { идентификатор: 'AB4_1'}]

Смежные вопросы