node.js - How to handle multithreading in database in nodejs?
问题描述
I have problems using the database in nodejs with mongodb. Specifically when I use findOne in the data loop. The result is that outp returns an empty value. Thanks everyone!
var room_members = cdb.get().collection('room_members');
var historys = cdb.get().collection('history');
var outp = [];
room_members.find({id_account: ObjectId(deToken._id)}).toArray(function (f_err, f_res) {
for (var i = 0; i < f_res.length;i++) {
historys.findOne({
id_room: ObjectId(f_res[i].id_room)
}, function (h_err, h_res) {
if (h_res) {
outp.push(h_res);
}
})
}
res.json({
status: ok,
message: outp
});
});
解决方案
As you're pushing element in outp
array in the callback of historys.findOne
,
and historys.findOne
doesn't block the thread, ie node won't wait for it to finish to continue execution, the callback isn't called when you call res.json
.
var room_members = cdb.get().collection('room_members');
var historys = cdb.get().collection('history');
var outp = [];
room_members.find({id_account: ObjectId(deToken._id)}).toArray(function (f_err, f_res) {
for (var i = 0; i < f_res.length;i++) {
historys.findOne({
id_room: ObjectId(f_res[i].id_room)
}, function (h_err, h_res) {
if (h_res) {
outp.push(h_res);
}
})
}
res.json({
status: ok,
message: outp
});
});
If you're using this library, if you don't pass a callback, you get a promise, so you can do like this :
var room_members = cdb.get().collection('room_members');
var historys = cdb.get().collection('history');
room_members.find({id_account: ObjectId(deToken._id)}).toArray(function (f_err, f_res) {
var promises = []
for (var i = 0; i < f_res.length;i++) {
promises.push(historys.findOne({
id_room: ObjectId(f_res[i].id_room)
}))
}
Promise.all(promises).then(function(output){
res.json({
status: ok,
message: output
});
}).catch(function(err){
// Handle the error here
})
)
});
And if you want to use async/await:
async function get_room_members_history(req, res) {
try {
// Do what you want to get you're deToken using req or whatever you want
var room_members = cdb.get().collection("room_members");
var historys = cdb.get().collection("history");
var rooms_members_array = await room_members
.find({ id_account: ObjectId(deToken._id) })
.toArray();
var promises = [];
for (var i = 0; i < rooms_members_array.length; i++) {
promises.push(
historys.findOne({
id_room: ObjectId(rooms_members_array[i].id_room)
})
);
}
var output = await Promise.all(promises);
res.json({
status: ok,
message: output
});
} catch (error) {
// Handle error here
}
}
推荐阅读
- javascript - 选择第一个可见元素的问题
- mongodb - 在mongodb中插入10000个数字元素怎么办?
- javascript - 如何录制 RTSP 流
- java - 如何从 Java 中的 mongo 连接器返回 xml?
- mysql - 具有属性的产品的数据模型,每个属性组合具有不同的价格
- android - google-services-auth 与 kommunicate 崩溃
- c++ - 如何使用 Boost 库构建 MEX 函数?
- python - Django:类型对象'CategoryAttributeInlineForm'没有属性:'_meta'
- json - 如何解析具有未知结构Golang的嵌套json文件
- android - 使用 proguard 进行库混淆