Sql 续集承诺-链接承诺和蓝鸟承诺.each、Promise.map、Promise.all等

Sql 续集承诺-链接承诺和蓝鸟承诺.each、Promise.map、Promise.all等,sql,node.js,promise,sequelize.js,bluebird,Sql,Node.js,Promise,Sequelize.js,Bluebird,在我的用户控制器中有一个索引操作,其中我尝试在一行中执行两件事,并且在它们都有机会完成之前不执行所需的res.json()方法 我有一个加入用户的友谊加入模型。一列是frienderId,另一列是frienderId。在下面的索引函数中,期望的结果是我将得到一个用户对象,它是一个朋友。下面之所以要承诺,是因为用户可能在frienderId列或frienderId列中,所以我必须对req.user的friends解析这两种可能的情况 问题是,返回的最后一个对象,即res.json(result),

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

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

问题是,返回的最后一个对象,即res.json(result),总是返回正确的friend,但是,它总是在所需对象之前或之后返回空数组[]。我知道这个空数组来自两个promise场景中的一个,在这两个场景中没有找到任何结果。是否存在某种类型的方法而不是像sayyy..拒绝这样的解决方法?其中,如果调用,整个承诺不会被推送到承诺数组中?然后我可以测试一下(!friended){reject}或者(!friender){reject}

我明白。每个人都在列举每个承诺,并给出每个承诺的结果。但是,我不想看到每个承诺的结果,我只想看到每个承诺运行的副作用

谢谢

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

首先,您使用的
Promise
有点多余。由于
findById()
函数返回一个承诺,所以只需处理它。您不需要创建
新承诺
。您可以只说
promiseArray.push(user.findById…)
。您几乎正确地使用了
。传递到
then
中的函数是在
findById
函数完成并返回值后,在解析承诺时将调用的函数
然后
本身返回一个承诺,该承诺使用其回调返回的值进行解析。因此,当所有操作完成后,无论您希望在promiseArray中得到什么值,我假设
Friented[0]
friender[0]
您只需要在上一个
函数中返回该值即可。在第一个
then
函数中,还应该说
returnuser.findFriends(…

接下来需要做的是处理从
findById
函数返回的承诺被拒绝的情况。您可以通过两种方式来完成。首先,您可以将第二个回调传递给
,然后在承诺被拒绝的情况下将调用该回调,并将拒绝的原因作为其参数。而不是传递两个函数进入
then
,您可以使用
catch
跟随
then
,这是我个人喜欢做的,并将您的拒绝回调传递给
catch
catch
也会返回一个承诺,该承诺通过回调返回的值得到解决。您可以选择返回传入的原因,或任何值因此,在错误被拒绝的情况下,
catch
返回的结果就是Promissions数组中的结果

仔细阅读承诺可能会对你有所帮助。诚然,我知道我刚开始时在承诺方面遇到了一些困难,但在阅读了文档并编写了示例之后,你会了解到承诺是多么有用

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

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

你可以把所有的东西都保持不变。在最后,你仍然可以调用<代码>序列化< /代码>,虽然它应该是<代码>返回顺序……/>代码。你也可以考虑使用<代码>承诺>过滤器< /代码>而不是<代码>。map < /C> >如果你不想保留坏的结果。那么你可以做一些类似

的事情。
    return Sequelize.Promise.filter(promiseArray, function(result) {
      if (/* make sure it's result you want */)
        res.json(result);
    });
就我个人而言,我会更进一步,将所有promise业务移到另一个不使用
res
的函数中,并使用

    return Sequelize.Promise.filter(promiseArray, function(result) {
      return result === /* result you want */;
    });
然后一旦进入
索引
函数,就可以调用

    return friendsPromiseFunction().then(function (results) {
      res.json(results);
    })

这会让事情变得更干净。

另一件奇怪的事情是,当我不在最底部简单地使用res.json(result),而是在最顶部的var promiseArray下添加一个未定义的变量,称为var-friend,然后是console.log(friend)在Sequelize.Promise.map函数的末尾,结果是两个值。第一个值未定义,第二个值是正确的friend对象,反之亦然,具体取决于用户所在的列(frienderId或frienderId)。非常困惑,在控制台中记录一个变量会导致记录两个完全不同的值,一个接一个。Thx。我最终没有使用Bluebird Promise方法,而是使用常规sequelize Promise链。这个过程对我来说是一个实验,我没有意识到我可以ld在FRIENDED上做一个查询,然后简单地使用。然后调用FRIENDER并对FRIENDER执行相同的查询,然后我就可以开始了。然后我可以访问FRIENDED和FRIENDER作为返回值,在承诺链中进行两次查询,没有任何问题。感谢您的帮助!赞成票。