This question already has an answer here:
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!
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