使用递归的异步数据库调用
Async db calls using recursion
我需要递归下降链表数据库树
item 1-> item 2
-> item 3 -> item 4
-> item 5 -> item 6 -> item 7
-> item 8
我的伪代码是
var getItems = function(itemid) {
db.getitem(itemid, function(item) {
item.items.forEach(function(subitem) {
getItems(subitem.id)
})
})
getItems(1)
然而,db.getItem
是一个异步函数
我想return一个和图一样结构的JS对象给顶级调用者
实现此目标的最佳方法是什么?我不知道预先的结构(即不知道每个项目的项目数量,或树中任何分支的深度)所以我不知道我需要处理的项目数量
我尝试了异步库的各种方法,但是none似乎可以处理递归
这就是强大的并发原语大放异彩的地方。
Promises 让你很容易做到这一点:
// with bluebird this is var getItem = Promise.promisify(db.getitem);
var getItem = function(itemid){
return new Promise(function(resolve, reject){
db.getitem(itemid, function(err, data){
if(err) reject(err);
else resolve(data);
});
});
};
哪个会让你做:
var getItems = function(itemid) {
return getItem(itemid).then(function(item){ // get the first
return Promise.all(item.items.forEach(function(subItem){
return getItems(subitem.id);
});
}).then(function(subItems){
var obj = {};
obj[itemid] = subItems; // set the reference to subItems
return obj; // return an object containing the relationship
});
};
getItems(1).then(function(obj){
// obj now contains the map as you describe in your problem description
});
这是 async
的样子:
var getItems = function(itemid, callback){
db.getitem(itemid, function(err, item){
if(err) return callback(err, null);
async.map(item.items, function(subitem, cb){
getItems(subitem.id, cb);
}, function(err, results){
if(err) return callback(err, null);
var obj = {};
obj[itemid] = result;
return callback(null, obj);
});
});
};
它非常接近,但我认为它比 promise 版本差很多。
我需要递归下降链表数据库树
item 1-> item 2
-> item 3 -> item 4
-> item 5 -> item 6 -> item 7
-> item 8
我的伪代码是
var getItems = function(itemid) {
db.getitem(itemid, function(item) {
item.items.forEach(function(subitem) {
getItems(subitem.id)
})
})
getItems(1)
然而,db.getItem
是一个异步函数
我想return一个和图一样结构的JS对象给顶级调用者
实现此目标的最佳方法是什么?我不知道预先的结构(即不知道每个项目的项目数量,或树中任何分支的深度)所以我不知道我需要处理的项目数量
我尝试了异步库的各种方法,但是none似乎可以处理递归
这就是强大的并发原语大放异彩的地方。
Promises 让你很容易做到这一点:
// with bluebird this is var getItem = Promise.promisify(db.getitem);
var getItem = function(itemid){
return new Promise(function(resolve, reject){
db.getitem(itemid, function(err, data){
if(err) reject(err);
else resolve(data);
});
});
};
哪个会让你做:
var getItems = function(itemid) {
return getItem(itemid).then(function(item){ // get the first
return Promise.all(item.items.forEach(function(subItem){
return getItems(subitem.id);
});
}).then(function(subItems){
var obj = {};
obj[itemid] = subItems; // set the reference to subItems
return obj; // return an object containing the relationship
});
};
getItems(1).then(function(obj){
// obj now contains the map as you describe in your problem description
});
这是 async
的样子:
var getItems = function(itemid, callback){
db.getitem(itemid, function(err, item){
if(err) return callback(err, null);
async.map(item.items, function(subitem, cb){
getItems(subitem.id, cb);
}, function(err, results){
if(err) return callback(err, null);
var obj = {};
obj[itemid] = result;
return callback(null, obj);
});
});
};
它非常接近,但我认为它比 promise 版本差很多。