Javascript 返回一个使用嵌套承诺构建的对象
我正在努力将我的脑袋绕到嵌套的promise布局上,在该布局的末尾返回一个对象。我目前的代码如下: 路由器Javascript 返回一个使用嵌套承诺构建的对象,javascript,node.js,promise,Javascript,Node.js,Promise,我正在努力将我的脑袋绕到嵌套的promise布局上,在该布局的末尾返回一个对象。我目前的代码如下: 路由器 router.get(`/${config.version}/event/:id?`, function (req, res, next) { var event = new Event(req, res, next); event.getInfo(req.params.id).then((info) => { res.send(info);
router.get(`/${config.version}/event/:id?`, function (req, res, next) {
var event = new Event(req, res, next);
event.getInfo(req.params.id).then((info) => {
res.send(info);
});
});
作用
getInfo(id) {
db.main('events').where('id', id).select()
.then((result) => {
if(result.length > 0) {
var event = result[0];
//regular functions
event.status = this.getStatus(id);
event.content = this.getContent(id);
event.price = this.getPrice(id);
//promise functions
var users = this.getUsers(id);
var hosts = this.getHosts(id);
Promise.all([users, hosts]).then(values => {
event.users = values[0];
event.hosts = values[1];
//return whole event object to router
return event;
})
.catch((err) => {
return {
result: 'error',
error: err
};
});
} else {
return {
result: 'error',
error: "Event does not exist"
};
}
}).catch((e) => {
return {
result: 'error',
error: "Could not retrieve event info"
};
});
}
如您所见,路由器发起一个呼叫以获取有关事件的信息。然后,该函数执行数据库调用并获取一些事件数据。此后,我需要从不同的表中获取事件的用户和主机,并将该信息附加到事件对象,然后将整个对象返回到路由器以发送到客户端
当我这样做的时候,我会得到一个错误,因为我没有从getInfo函数返回一个承诺,但是我不确定应该如何返回或者返回哪个承诺
我很感激你能帮我。谢谢只需将异步代码包装在Promise中,如下所示:
getInfo(id) {
return new Promise(function(resolve, reject) {
db.main('events').where('id', id).select()
.then((result) => {
//...
resolve(/* result */)
// OR
reject(/* Error */)
})
}
注意:使用resolve and reject代替returnusing。这表示您正在返回承诺
function getInfo(id) {
return new Promise(function(resolve, reject) {
resolve('yay!');
})
}
getInfo().then(function(result) { //result = yay! });
要使代码正常工作,只需用resolves替换所有返回,用rejects替换错误,并像我一样用return-new-Promise包装整个过程
getInfoid{
返回新的允诺函数解析、拒绝{
db.main'events'。其中'id',id.select
.thenresult=>{
如果result.length>0{
var事件=结果[0];
//正则函数
event.status=this.getStatusid;
event.content=this.getContentid;
event.price=this.getPriceid;
//承诺功能
var users=this.getUsersid;
var hosts=this.getHostsid;
承诺。所有[用户,主机]。然后值=>{
event.users=值[0];
event.hosts=值[1];
//将整个事件对象返回到路由器
解决事件;
}
.catcherr=>{
拒绝{
结果:“错误”,
错误:错误
};
};
}否则{
拒绝{
结果:“错误”,
错误:事件不存在
};
}
}.catch=>{
拒绝{
结果:“错误”,
错误:无法检索事件信息
};
};
};
} 这是几件事的组合,但最主要的一件事是,你永远不会从getInfo返回任何东西,所以你的路由器处理程序正在调用 不要打电话。如果你打算回电让打电话的人消费的话,不要把承诺扔进去。这使得无法使用.catch,因为您已将承诺链恢复为已解决的承诺链 无论你在一个.中返回什么,它都将被合并到承诺链中,因此它实际上不是一个用承诺来解决的承诺。您的整个代码可以替换为: 获取信息id{ 返回db.main'events'。其中'id',id.select .thenresult=>{ 如果result.length==0{ //你也可以抛出你的错误对象, //但标准误差通常是惯例 抛出新错误“事件不存在” } 常量[事件]=结果 event.status=this.getStatusid event.content=this.getContentid event.price=this.getPriceid 返回Promise.all[this.getUsersid,this.getHostsid] 。然后[用户、主机]=>{ event.users=用户 event.hosts=主机 //这是唯一一个 //this.getInfoid.thenvalue=>{/*…*/}将看到 返回事件 } } }
昨晚我遇到了这个问题,我很好奇最佳实践是什么,或者是否已经有了答案。@也许最简单的方法是用承诺来包装代码,然后在收集完所有数据后调用resolve。在我的例子中,我从承诺中调用了包装承诺的解析。所有…,然后…,就像你在Ahmed的回答中看到的那样。如果db.main.select.then已经是一个承诺,那么当你已经有一个承诺可以返回时,将一个承诺包装在另一个承诺中是一种反模式。代码也会简单得多。我们如何确定这是一个承诺?或者如果它有。那么确定它返回了一个承诺,对吗?您可以阅读您正在使用的数据库的文档,或者查看代码,以了解是否确实有类似承诺的行为。现在,大多数星展银行都内置了promise选项,因为这是一种更好的使用方式。A.然后意味着承诺,但有一些拙劣的模仿不符合承诺,因此有必要找出它们是否是真正的承诺。@AhmadBamieh如果你不确定这是一个真正的承诺,但它是一个真实的承诺,那么就用承诺来包装它。resolve@Kovensky你能建议对我的代码进行编辑,让我知道具体操作方法吗?我明白你的意思,但我不知道它是怎么工作的。