我在我的用户控制器中有一个索引操作,其中我试图做两件事,在一行中,并且不执行所需的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
,你可以跟着then
和catch
,这是我个人更喜欢做的,并传递你的拒绝回调给catch
。catch
还返回一个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);
})