Promise chaining: Use result from previous promise in next then callback [duplicate]

ぃ、小莉子 提交于 2019-12-30 10:38:12

问题


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:

  1. store the student in a variable in an outer scope (yuck)
  2. I actually don't know how this would work, but the solutions in the other question suggest I can call then on the result of HelpRequest.findByStudent() and Promise.resolve the combined result inside the Student.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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!