[英]Javascript asynchronous calls chaining
給定一個包含A和B類型對象的數組,其中B可以通過異步調用轉換為一組A類型對象,這將是將數組轉換為全A對象數組的最佳方法(轉換每個B對象在一組相應的A對象中)並在轉換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
}
好吧,你需要在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(有許多實現是一種更好的方法。它們可能會更復雜一些,但是具有非常好的屬性並且會產生簡潔明了的語法。在你的情況下,它會是
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); }
這是一個完整的異步工作示例:
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'}]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.