承诺链接:在接下来的回调中使用以前承诺的结果 [英] Promise chaining: Use result from previous promise in next then callback
问题描述
我正在使用直接的ES6 Promises(与es6承诺的polyfill库),我遇到一个问题,访问以前的链接链接中的结果。
I'm using straight ES6 Promises (with the es6-promise polyfill library) and I'm running into a problem with accessing results from previous promises in chained ones.
这个问题在Angular / Q的上下文中是一样的,但是我不满意答案,想看看是否有更好的方法:
This problem is identical in the context of Angular/Q, but I'm dissatisfied with the answer and wanted to see if there's a better way:
考虑以下代码片段:
Student.find().then(function(student) {
return HelpRequest.findByStudent(student);
}, function(error) { //... }
).then(function(helpRequest) {
// do things with helpRequest...
// PROBLEM: I still want access to student. How can I get access to it?
});
在链接的承诺中,我想使用学生
对象,我得到了第一个承诺。但是如书面所述,这是无法访问的。我有几个明显的选择:
In the chained promise, I want to use the student
object that I got in the first promise. But as written, this can't access it. I have a couple apparent options:
- 将学生存储在外部范围(yuck)中的变量中
我实际上不知道这是如何工作的,但另一个问题的解决方案表明我可以调用
然后
对 HelpRequest.findByStudent()
和 Promise.resolve
Student.find()中的组合结果然后
调用。以下的实现方式不行,我想,但是,- store the student in a variable in an outer scope (yuck)
I actually don't know how this would work, but the solutions in the other question suggest I can call
then
on the result ofHelpRequest.findByStudent()
andPromise.resolve
the combined result inside theStudent.find().then
call. The below implementation won't work I think, though.
Student.find().then(function(student) {
var data = {student: student};
HelpRequest.findByStudent(student).then(function(helpRequest) {
data.helpRequest = helpRequest;
});
// PROBLEM: if HelpRequest.findByStudent(student) is asynchronous, how
// does this get the data before returning?
return data;
}, function(error) { //... }
).then(function(helpRequest) {
// do things with helpRequest and student
});
我绝对不想做处理 helpRequest
嵌套在 Student.find()
方法之内,因为这违反了链接Promises的目的;即使第二个例子可以处于可用状态,它仍然感觉像一个黑客。
I absolutely don't want to do the processing of the helpRequest
nested inside of the Student.find()
method, as that defeats the purpose of chaining Promises; and even if the second example can be worked into a usable state, it still feels like a hack.
有没有更好的方法来实现这一点,而不必引入全局状态或嵌套到我的代码?例如,有没有办法在多个值上调用 Promise.resolve()
,其中一些可能是承诺,其中一些不是?
Is there a better way to do achieve this without having to introduce global state or nesting into my code? For instance, is there a way to call Promise.resolve()
on multiple values, some of which may be promises and some of which are not?
我很好奇,希望我有其他选择/可以理解如何使这个工作正常,而不会引入嵌套或状态!
I'm curious, hope I have alternatives/can understand how to make this work properly without introducing nesting or state!
推荐答案
在我看来,承诺的禅意在于确定他们只是异步的价值观。如果您开始使用它们,这些问题在许多情况下变得更加简单。这不是一个银弹,但确实有帮助:
In my opinion, the zen of promises is all about figuring out they're really just asynchronous values. If you start using them as such these problems become simpler in many cases. It's not a silver bullet but it sure does help:
在ES5中:
var student = Student.find();
var helpRequest = student.then(HelpRequest.findByStudent);
Promise.all([student, helpRequest]).then(function(results){
var student = results[0];
var helpRequest = results[1];
// access both here
});
在ES6中,其所有功能:
In ES6, with all its features:
var student = Student.find();
var helpRequest = student.then(HelpRequest.findByStudent);
Promise.all([student, helpRequest]).then(([student, helpRequest]) => {
// access both here
});
在另一个更丰富的承诺图书馆(蓝鸟)中:
In another richer promise library (bluebird):
var student = Student.find();
var helpRequest = student.then(HelpRequest.findByStudent);
Promise.join(student, helpRequest, function(student, helpRequest){
// access both here
});
这篇关于承诺链接:在接下来的回调中使用以前承诺的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!