Promise chain: use the result of the previous promise in the next callback
I am using straight ES6 Promises (with es6-prom polyfill library) and I am having problem accessing the results of previous Promises in the chain.
This problem is identical in the Angular / Q context, but I'm not happy with the answer and want to see if there is a better way:
How do I get the result from the previous promise in the 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 a pivot promise, I want to use the object student
I received in the first promise. But as written, this cannot access it. I have several obvious options:
- store the student in a variable in the outer scope (yuck)
-
I don't really know how this would work, but the solutions in the other question assume that I can call the
then
resultHelpRequest.findByStudent()
and thePromise.resolve
combined result within theStudent.find().then
call. The implementation below will not work I guess.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 helpRequest
nest the processing inside the method Student.find()
, as that defeats the purpose of chaining Promises; and even though the second example can be processed in a usable state, it still looks like a hack.
Is there a better way to achieve this without introducing global state or nesting it into my code? For example, is there a way to call Promise.resolve()
for multiple values, some of which may be Promises and some of which are not?
I'm curious, hopefully I have alternatives / can figure out how to do this correctly without introducing nesting or state!
source to share
In my opinion, Zen promises are all about understanding that they are really just async values. If you start using them as such, in many cases these problems will become easier. It's not a silver bullet, but it 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 rich promise library (bluebird):
var student = Student.find();
var helpRequest = student.then(HelpRequest.findByStudent);
Promise.join(student, helpRequest, function(student, helpRequest){
// access both here
});
source to share