我想对我使用loopback设计的API之一进行同步调用。这是我的代码:
router.get('/friends', function(req, res, Array) {
var friendsList = []
for(var counter=0;counter<length;counter++){
Model.findById(Array[counter].Id,function(err, record) {
if(record){
friendsList.push(record);
}
});
}
res.status(200).json(friendsList);
});
现在我在数组之前获得响应, friendList 正在完全填充。我想让它同步并获得正确的响应。我该怎么办?
谢谢!
答案 0 :(得分:3)
一种简单的方法是
length
res.status...
像这样:
router.get('/friends', function(req, res, array) {
var friendsList = [];
var remaining = length;
for(var counter=0;counter<length;counter++){
Model.findById(array[counter].Id, function(err, record) {
if (record){
friendsList.push(record);
}
remaining -= 1;
if (remaining == 0) {
res.status(200).json(friendsList);
}
});
}
});
为了完整性...因为您正在使用nodejs ...使用(本机)Promise和arrow function
语法
router.get('/friends', (req, res, array) =>
Promise.all(array.map(item =>
new Promise((resolve, reject) =>
Model.findById(item.Id, (err, record) =>
resolve(record || undefined)
)
)
))
.then(friendsList =>
res.status(200).json(friendsList.filter(item =>
item !== undefined
))
)
);
答案 1 :(得分:1)
我使用async
和underscore
模块
var async = require('async');
var _ = require('underscore');
router.get('/friends', function(req, res, Array) {
var friendsList = [];
var waterfallFunctions = [];
_.each(Array, function(element) {
waterfallFunctions.push( function(next) {
Model.findById(element.Id,function(err, record) {
if (err) return next(err);
if(record){
friendsList.push(record);
}
next();
});
});
});
//async waterfall calls the functions in the array in order.
async.waterfall(waterfallFunctions, function (err) {
if (err) return res.status(500);
res.status(200).json(friendsList);
});
});
答案 2 :(得分:0)
使用Promise和Mongoose中的SkipWhile
运算符:
reeks.SkipWhile(n => n >= 1000 || n <= 10).TakeWhile(n => n < 1000 && n > 10)
$in
从数组中选择第一个router.get('/friends', function(req, res, arr) {
var promise = Model.find({ _id: { $in: arr.slice(0, length).map(function (e) { return e.Id }) } }).exec()
promise.then(function (friendsList) {
res.status(200).json(friendsList)
})
})
元素。 arr.slice
创建一个查询,这比执行多个length
查询更有效。 Model.find
运算符接受一组id来进行查找。 findById
创建一个承诺,使用$in
解决。
答案 3 :(得分:0)
你应该等到N个findById调用完成,所以解决方案是制作一个promises数组并使用Promise.all方法。
router.get('/friends', function(req, res, Array) {
var friendsList = []
var friendsPromises = []
for (var counter=0; counter<length; counter++) {
var friend = Model.findById(Array[counter].Id;
friendsList.push(friend)
friend.then(function(record) {
if (record) {
friendsList.push(record);
}
})
}
Promise.all(friendsPromises).then(function(){
res.status(200).json(friendsList);
})
});