Javascript 如何通过中间阶段传递承诺结果
我试图在承诺的各个步骤之间传递中间值,但我找不到一种干净的方法来实现。作为一个用例,这似乎很常见,所以我希望我只是缺少了一个模式,而不是完全偏离了轨道 我使用Bluebird作为承诺,使用Sequelize(SQLORM) 示例代码:Javascript 如何通过中间阶段传递承诺结果,javascript,promise,sequelize.js,bluebird,Javascript,Promise,Sequelize.js,Bluebird,我试图在承诺的各个步骤之间传递中间值,但我找不到一种干净的方法来实现。作为一个用例,这似乎很常见,所以我希望我只是缺少了一个模式,而不是完全偏离了轨道 我使用Bluebird作为承诺,使用Sequelize(SQLORM) 示例代码: db.sync().then(function () { // When DB ready, insert some posts return [ BlogPost.create(), BlogPost.create
db.sync().then(function () {
// When DB ready, insert some posts
return [
BlogPost.create(),
BlogPost.create()
];
}).spread(function (post1, post2) {
// Once posts inserted, add some comments
return [
post1.createComment({ content: 'Hi - on post 1' }),
post2.createComment({ content: 'Hi - on post 2' })
];
}).spread(function (post1, post2) { // THE PROBLEM: Want posts here, not comments
// Do more with posts after comments added, e.g. add tags to the posts
// Can't do that in the above as something needs to wait for
// comment creation to succeed successfully somewhere.
// Want to wait on Comments promise, but keep using Posts promise result
});
到目前为止,我拥有的最佳解决方案是:
db.sync().then(function () {
// When DB ready, insert some posts
return [
BlogPost.create(),
BlogPost.create()
];
}).spread(function (post1, post2) {
// Once posts inserted, add some comments
return Promise.all([
post1.createComment({ content: 'Hi - on post 1' }),
post2.createComment({ content: 'Hi - on post 2' })
]).then(function () {
// Extra nested promise resolution to pull in the previous results
return [post1, post2];
});
}).spread(function (post1, post2) {
// Do things with both posts
});
当然还有更好的办法吗?Bluebird有,非常接近,但没有做spread()部分,我找不到一个简单的方法来组合。我关闭了这个,但后来又重新打开,因为您的问题比一般问题具体得多。关于一般问题 对于上面一个操作的特定上下文-您可以将
.return
与bluebird一起使用以覆盖返回值:
db.sync().then(function () {
...
}).spread(function (post1, post2) {
return Promise.all([
post1.createComment({ content: 'Hi - on post 1' }),
post2.createComment({ content: 'Hi - on post 2' })
]).return([post1, post2]); // use .return here
}).spread(function (post1, post2) { comments
// posts here
});
经过进一步调查,我仍然找到了更好的答案(0承诺嵌套):
请注意轻敲之前的.all():这确保在轻敲()之前正确展开first-then()的结果,并允许您正常使用轻敲。仍然不能为您提供spread()支持,但它已经足够接近了。这种方法的一种变体是“不扩散”。通过使用
.then(function(posts){…}
可以返回Promise.all(…).return(posts)
而不必重新处理原始数据。当然,您必须执行posts[0].createComment(…)
和posts[1].createComment(…)
但这可能不是什么坏事。不管怎样都没什么大不了的——至少在已知的少量帖子中没有。
db.sync().then(function () {
// When DB ready, insert some posts
return [
BlogPost.create(),
BlogPost.create()
];
}).all().tap(function (posts) {
// Once posts inserted, add some comments
return [
posts[0].createComment({ content: 'Hi - on post 1' }),
posts[1].createComment({ content: 'Hi - on post 2' })
]
}).spread(function (post1, post2) {
// Do things with both posts
});