我使用promise.each
使用bookshelfjs
循环2 db查询,但是角色没有给我结果 - > roles[resource.get('name')] = role.get('name');
,但是它给了我slect语句中的对象:
var promise = new Promise(
function resolver(resolve, reject) {
var roles = {};
Promise.each(user.relations.relates.models, function(relation){
return Resource.forge({resourceId: relation.get('resourceId')}).fetch().then(function(resource){
return Role.forge({roleId: relation.get('roleId')}).fetch().then(function(role){
roles[resource.get('name')] = role.get('name');
return roles;
}).catch(function(err){
reject({"status":"error", "data": err});
});
}).catch(function(err){
reject({"status":"error", "data": err});
});
}).then(function(roles){
resolve(roles);
});
}
);
return promise;
答案 0 :(得分:2)
来自Promise.each()
的Bluebird文档:
解析为未修改的原始数组,此方法的意思是 用于副作用。
所以,这意味着当你这样做时:
Promise.each(array).then(function(val) {
// iteration finished here
// val is the original array
});
val
将是您传入的原始数组,而不是您的roles
对象。
由于您的roles
对象位于更高的范围内,因此您可以删除roles
处理程序中声明为.then()
的参数,并直接引用更高范围的roles
变量
你也应该避免在这里promise constructor anti-pattern而不是创建一个新的承诺,而只是返回你已经拥有的承诺。
你可以这样做:
var roles = {};
return Promise.each(user.relations.relates.models, function (relation) {
return Resource.forge({resourceId: relation.get('resourceId')}).fetch().then(function (resource) {
return Role.forge({roleId: relation.get('roleId')}).fetch().then(function (role) {
roles[resource.get('name')] = role.get('name');
});
}).catch(function (err) {
// repackage how the error is presented into our own object
throw ({"status": "error", "data": err});
});
}).then(function () {
// make the resolved value of the final promise be the roles object
return roles;
});
此返回承诺的已解决值将是您的roles
对象。
更改摘要:
Promise.each()
返回承诺而不是创建新承诺(不需要在此创建新承诺)。.then()
的{{1}}处理程序中,删除名为Promise.each()
的声明参数,因为它与更高范围的roles
对象冲突。roles
处理程序中返回roles
,以便它成为您要返回的承诺的解析值。.then()
,因为外部.catch()
也可以执行此操作。.catch()
以抛出重新包装的错误值。.catch()
,因为不需要它。 return roles;
对象在更高的范围内始终可用,因此无需将其作为这些内部承诺的已解决值(事实上,这可能会造成混淆)。可能的性能优化。由于您的结果都不依赖于之前的结果,因此可能您可以并行运行所有异步操作而不是串行运行,在这种情况下,您可以将roles
替换为Promise.each()
。
答案 1 :(得分:1)
是的,对不起,我们改变主意了。
在3.x中,我们应该让.each
返回结果而不是原始值,但这会破坏很多人的代码,所以我们将其更改回来并添加了mapSeries
。< / p>
基本上,只要您使用.mapSeries
并关注结果,就会使用each
,它完全符合您的预期。如果您可以同时运行这些项目,请使用.map
,因为它可能会表现得更好。