返回使用嵌套承诺

时间:2016-08-08 20:59:09

标签: 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);
    });
});

功能

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,但我不确定我应该返回的承诺或承诺。

我很感激这方面的一些帮助。感谢

3 个答案:

答案 0 :(得分:1)

使用.then意味着您将返回一个承诺。

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

答案 1 :(得分:0)

将您的异步代码包装在Promise中,如下所示:

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

注意:使用resolvereject代替return

答案 2 :(得分:0)

它是几件事的组合,但主要的一点是你永远不会从deque返回任何东西,所以你的路由器处理程序在getInfo上调用.then。< / p>

请不要在undefined上调用.catch {而不是throw来打算调用者使用。这使得无法使用Promise,因为您已将.catch链恢复为已解析的链。

无论你在Promise内返回什么,都会被合并到承诺链中,所以它实际上并不是一个用承诺解决的承诺&#34;。您的整个代码可以替换为:

.then