续写承诺-链接承诺和蓝鸟承诺.每一个承诺.地图,承诺.所有等等



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

我有一个加入用户的友谊加入模型。一列是friendid,一列是frienddid。在下面的索引函数中,期望的结果是我将得到一个单个用户对象,它是一个朋友。下面有两个承诺的原因是,用户可能在friendid列中,也可能在frienddid列中,所以我必须解析这两种可能的情况来进行请求。用户的朋友。

问题是返回的最后一件事,即res.json(result),总是返回正确的朋友,然而,它总是返回一个空数组[],要么在所需对象之前,要么在它之后。我知道这个空数组来自没有发现结果的两个承诺场景之一。有没有什么方法可以代替resolve,比如reject?其中,如果调用,整个承诺不会被推到承诺数组?然后我可以测试if (!friender) {reject}或if (!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()函数返回一个promise,您所需要做的就是处理它。您不需要创建new Promise。你可以说promiseArray.push(user.findById ...)。你几乎正确地使用了then。传递给then的函数是在解析承诺时调用的函数,在本例中,是在findById函数完成并返回值之后。then本身返回一个promise,这个promise是用它的回调返回的值来解析的。因此,无论您想要在promise earray中结束的值是什么,我假设friended[0]friender[0],您只需要在最后的then函数中返回该值。在第一个then函数中,还应该写入return user.findFriends( ...

接下来你需要做的是处理从findById函数返回的承诺被拒绝的情况。有两种方法。首先,您可以向then传递第二个回调,该回调将在承诺被拒绝的情况下调用,并将拒绝的原因作为其参数。而不是传递两个函数到then,你可以跟着thencatch,这是我个人更喜欢做的,并传递你的拒绝回调给catchcatch还返回一个promise,该promise使用回调返回的值进行解析。你可以选择返回传入的原因,或者任何你想要的值。因此,在错误被拒绝的情况下,无论catch返回什么,都将在您的promises数组中结束。

阅读文档中的承诺可能对你有好处。不可否认,我知道我刚开始使用承诺时遇到了一些困难,但在浏览了文档并编写了示例之后,您就掌握了它,并看到了承诺是多么有用。

如果是我,我会这样重构代码

    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。你可以输入

    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 */;
    });
然后在index函数中,你可以调用
    return friendsPromiseFunction().then(function (results) {
      res.json(results);
    })

最新更新