Sql 续集承诺-链接承诺和蓝鸟承诺.each、Promise.map、Promise.all等
在我的用户控制器中有一个索引操作,其中我尝试在一行中执行两件事,并且在它们都有机会完成之前不执行所需的res.json()方法 我有一个加入用户的友谊加入模型。一列是frienderId,另一列是frienderId。在下面的索引函数中,期望的结果是我将得到一个用户对象,它是一个朋友。下面之所以要承诺,是因为用户可能在frienderId列或frienderId列中,所以我必须对req.user的friends解析这两种可能的情况 问题是,返回的最后一个对象,即res.json(result),总是返回正确的friend,但是,它总是在所需对象之前或之后返回空数组[]。我知道这个空数组来自两个promise场景中的一个,在这两个场景中没有找到任何结果。是否存在某种类型的方法而不是像sayyy..拒绝这样的解决方法?其中,如果调用,整个承诺不会被推送到承诺数组中?然后我可以测试一下(!friended){reject}或者(!friender){reject} 我明白。每个人都在列举每个承诺,并给出每个承诺的结果。但是,我不想看到每个承诺的结果,我只想看到每个承诺运行的副作用 谢谢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),
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作为返回值,在承诺链中进行两次查询,没有任何问题。感谢您的帮助!赞成票。