问题
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.
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:
How to access result from the previous promise in AngularJS promise chain?
Consider the code snippet below:
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:
- 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 });
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.
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!
回答1:
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:
In 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
});
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
});
来源:https://stackoverflow.com/questions/26902994/promise-chaining-use-result-from-previous-promise-in-next-then-callback