Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 返回一个使用嵌套承诺构建的对象_Javascript_Node.js_Promise - Fatal编程技术网

Javascript 返回一个使用嵌套承诺构建的对象

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

我正在努力将我的脑袋绕到嵌套的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);
    });
});
作用

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代替return

using。这表示您正在返回承诺

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你能建议对我的代码进行编辑,让我知道具体操作方法吗?我明白你的意思,但我不知道它是怎么工作的。