返回一个用嵌套promise构build的对象

我正在努力围绕一个嵌套的承诺布局,其中一个对象返回结束。 我目前的代码如下:

路由器

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); }); }); 

function

 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函数返回一个承诺,但我不知道如何或承诺我应该返回。

我会很感激这个帮助。 谢谢

那么就意味着你正在回复一个承诺。

 function getInfo(id) { return new Promise(function(resolve, reject) { resolve('yay!'); }) } getInfo().then(function(result) { //result = yay! }); 

为了使你的代码工作,只需用所有的返回结果,用拒绝代替错误,并用一个return new Promise包装整个事情,就像我做的那样。

 getInfo(id) { return new Promise(function(resolve, reject) { 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 resolve(event); }) .catch((err) => { reject({ result: 'error', error: err }); }); } else { reject({ result: 'error', error: "Event does not exist" }); } }).catch((e) => { reject({ result: 'error', error: "Could not retrieve event info" }); }); }); } 

只需在Promise中包装你的asynchronous代码就可以了:

 getInfo(id) { return new Promise(function(resolve, reject) { db.main('events').where('id', id).select() .then((result) => { //... resolve(/* result */) // OR reject(/* Error */) }) } 

注意:使用resolvereject而不是return

这是几件事情的结合,但最主要的是,你从来没有从getInfo返回任何东西,所以你的路由器处理程序正在调用.thenundefined

不要在Promise上调用.catch (没有throw它),你打算返回给调用者使用。 这使得无法使用.catch ,因为您.catch Promise链恢复为已解决的链。

无论你在内部回报什么.then都将被合并到诺言链中,所以它实际上并不是一个“以诺言解决的诺言”。 您的整个代码可以replace为:

 getInfo (id) { return db.main('events').where('id', id).select() .then(result => { if (result.length == 0) { // you can also just throw your error object thing, // but standard Error are generally the convention throw new Error('Event does not exist') } const [event] = result event.status = this.getStatus(id) event.content = this.getContent(id) event.price = this.getPrice(id) return Promise.all([this.getUsers(id), this.getHosts(id)]) .then(([users, hosts]) => { event.users = users event.hosts = hosts // this is the only value that // this.getInfo(id).then(value => {/* ... */}) will see return event } }) }