我正在使用Node.js和ExpressJS编写服务器。我的数据库是MongoDB,我使用MongooseJS作为中间件。
服务器有许多端点,并且几乎每个端点在开头都有相同的代码 - 查询DB以检索已分配给所选房间的设备。简化的重复代码如下:
Room
.findOne({ _id: roomId })
.populate({
path: "deviceGroups",
populate: {
path: "devices"
}
})
.exec(() => {
Device.findOne({ _id: deviceId }).exec((err, device) => {
if (err) {
res.send(err);
} else {
// do anything you need with the results here
}
});
});
我知道查询是异步的,所以如果我想对查询的结果做任何事情,我必须在查询的回调函数中执行。此外,在将查询提取到外部函数时,我猜有没有办法传递表达'res
对象,对吗?在查询期间需要处理潜在的错误。
我的问题是:考虑到有关asynchronysm的上述信息,是否可以创建一些自定义函数,如下图所示,即将检索即设备?函数的调用结果可以分配给某个变量。我想如果它完全可能,它应该包含一些JS的承诺处理程序,对吧?
我想要实现的是减少重复代码的数量。
原型功能:
const getDevice = (roomId, deviceId) => {
Room
.findOne({ _id: roomId })
.populate({
path: "deviceGroups",
populate: {
path: "devices"
}
})
.exec(() => {
Device.findOne({ _id: deviceId }).exec((err, device) => {
return device;
});
});
};
如果Room.exec尚未返回具有then
和catch
的内容,则可以创建承诺
function getDivice(roomId){
return new Promise(
(resolve,reject)=>
Room
.findOne({ _id: roomId })
.populate({
path: "deviceGroups",
populate: {
path: "devices"
}
})
.exec(() => {
Device.findOne({ _id: deviceId }).exec((err, device) => {
if (err) {
reject(err);
} else {
resolve(device);
// do anything you need with the results here
}
});
})
);
}
//call it like this:
getDivice(someid)
.then(
divice=>{
//do something with divice
}
)
.catch(
err=>{
//do something with the error
}
)