首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sequelize Promises链接Promise和Bluebird Promise.each、Promise.map、Promise.all等

Sequelize Promises链接Promise和Bluebird Promise.each、Promise.map、Promise.all等
EN

Stack Overflow用户
提问于 2016-09-20 06:36:42
回答 1查看 3.5K关注 0票数 3

我在用户控制器中有一个索引操作,其中我试图连续做两件事,并且在它们都有机会完成之前不执行所需的res.json()方法。

我有一个加入用户的友情加入模型。一列是frienderId,另一列是friendedId。在下面的索引函数中,期望的结果是我将得到一个单独的user对象,它是一个朋友。下面有promises的原因是因为用户可以在frienderId列中,也可以在friendedId列中,所以我必须解析req.user的朋友这两种可能的情况。

问题是返回的最后一件事,即res.json(result),总是返回正确的朋友,然而,它总是在所需对象之前或之后返回一个空的array []。我知道这个空数组来自两个未找到结果的promise场景之一。是否存在某种类型的方法,而不是像sayyy..reject那样的解析?其中,如果调用,整个promise不会被推送到promise数组中?然后我可以只测试(!friended) {reject}或(!friender) {reject}

我知道.each会枚举每个promise并给出每个promise的结果。然而,我不想要每个承诺的结果,我只想了解每个承诺运行的副作用。

谢谢!

代码语言:javascript
复制
index: function(req, res) {
    var promiseArray = [];

    promiseArray.push(new Promise(function(resolve) {
      user.findById(req.user.id).then(function(user) {
        user.getFrienders({
          where: {
            username: req.body.username
          }
        }).then(function(friender) {
          resolve(friender[0])
        })
      })
    }));

    promiseArray.push(new Promise(function(resolve) {
      user.findById(req.user.id).then(function(user) {
        user.getFriendeds({
          where: {
            username: req.body.username
          }
        }).then(function(friended) {
          resolve(friended[0])
        })
      })
    }));

    Sequelize.Promise.map(promiseArray, function(result) {
      res.json(result);
    });
}
EN

回答 1

Stack Overflow用户

发布于 2016-09-20 07:32:27

首先,您对Promise的使用有点多余。因为findById()函数返回一个promise,所以您需要做的就是处理它。您不需要创建new Promise。你可以直接说promiseArray.push(user.findById ...)。您几乎可以正确地使用then了。传递给then的函数将在解析promise时调用,在本例中,是在findById函数完成并返回一个值之后调用的。then本身返回一个promise,该promise由其回调返回的值解析。因此,无论您希望在完成所有操作后返回promiseArray中的任何值,我假定为friended[0]friender[0],您只需在最后一个then函数中返回该值。在第一个then函数中,您还应该使用return user.findFriends( ...

下一步需要做的是处理从findById函数返回的promise被拒绝的情况。您可以通过两种方式来完成此操作。首先,您可以将第二个回调传递给then,该回调将在promise被拒绝的情况下调用,其参数为reject的原因。不用将两个函数传递给then,您可以在then后面加上catch,这是我个人喜欢做的事情,并将您的拒绝回调传递给catchcatch还返回一个promise,该promise将使用其回调返回的值进行解析。你可以选择返回传入的原因,或者任何你想要的值。因此,在错误被拒绝的情况下,无论catch返回什么,最终都会出现在promises数组中。

阅读一下the documentation中的promises可能会对你有所帮助。诚然,当我刚开始的时候,我知道我在使用promises时遇到了一些困难,但在阅读了文档并制作了示例之后,您就会掌握它,并看到promises是多么有用。

如果是我,这就是我重构代码的方式

代码语言:javascript
复制
    var frienderPromise = user.findById(req.user.id)
          .then(function(user) {
            return user.getFrienders({
              where: { username: req.body.username }
            });
          })
          .then(function (friender) {
            return friender[0];
          })
          .catch(function (reason) {
            return reason; // or whatever else you want to end up in the promisesArray on rejection
          });

    var friendedPromise = user.findById(req.user.id)
          .then(function(user) {
            return user.getFriendeds({
              where: { username: req.body.username }
            });
          })
          .then(function (friended) {
            return friended[0];
          })
          .catch(function (reason) {
            return reason;
          });

    promiseArray.push(frienderPromise);
    promiseArray.push(friendedPromise);

你可以保持其他一切不变。最后,您仍然可以像当前一样调用Sequalize。虽然它应该是return Sequalize...。如果不想保留糟糕的结果,还可以考虑使用Promise.filter而不是.map。所以你可以像这样做

代码语言:javascript
复制
    return Sequelize.Promise.filter(promiseArray, function(result) {
      if (/* make sure it's result you want */)
        res.json(result);
    });

就我个人而言,我会更进一步,将所有的promise业务移到另一个与res无关的函数中,并以

代码语言:javascript
复制
    return Sequelize.Promise.filter(promiseArray, function(result) {
      return result === /* result you want */;
    });

然后,一旦进入index函数,您就可以调用

代码语言:javascript
复制
    return friendsPromiseFunction().then(function (results) {
      res.json(results);
    })

这会让事情变得更干净。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39583099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档