承诺链接:在接下来的回调中使用以前承诺的结果 [英] Promise chaining: Use result from previous promise in next then callback

查看:134
本文介绍了承诺链接:在接下来的回调中使用以前承诺的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用直接的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:

如何访问AngularJS承诺中以前承诺的结果链?

考虑以下代码片段:

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. 将学生存储在外部范围(yuck)中的变量中

  2. 我实际上不知道这是如何工作的,但另一个问题的解决方案表明我可以调用然后 HelpRequest.findByStudent() Promise.resolve Student.find()中的组合结果然后调用。以下的实现方式不行,我想,但是,

  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
});


我绝对不想做处理 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆