如何使用Promises链接和分享先前的结果 [英] How to chain and share prior results with Promises

查看:125
本文介绍了如何使用Promises链接和分享先前的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用bluebird库,需要发出一系列HTTP请求,并需要将一些响应数据发送到下一个HTTP请求。我已经构建了一个处理我的请求的函数,名为 callhttp()。这需要一个URL和POST的正文。

I'm using the bluebird library and need to make a series of HTTP requests and need to some of the response data to the next HTTP request. I've built a function that handles my requests called callhttp(). This takes a url and the body of a POST.

我这样称呼它:

var payload = '{"Username": "joe", "Password": "password"}';
var join = Promise.join;
join(
    callhttp("172.16.28.200", payload),
    callhttp("172.16.28.200", payload),
    callhttp("172.16.28.200", payload),
    function (first, second, third) {
    console.log([first, second, third]);
});

第一个请求获取需要传递给第二个请求的API密钥,依此类推。如何从第一个请求获取响应数据?

The first request gets an API key which needs to be passed to the second request and so on. How do get the response data from the first request?

UPDATE

这是 callhttp 函数:

var Promise = require("bluebird");
var Request = Promise.promisify(require('request'));

function callhttp(host, body) {

    var options = {
        url: 'https://' + host + '/api/authorize',
        method: "POST",
        headers: {
            'content-type': 'application/json'
        },
        body: body,
        strictSSL: false
    };

    return Request(options).spread(function (response) {
        if (response.statusCode == 200) {
           // console.log(body)
            console.log(response.connection.getPeerCertificate().subject.CN)
            return {
                data: response.body
            };
        } else {
            // Just an example, 200 is not the only successful code
            throw new Error("HTTP Error: " + response.statusCode );
        }
    });
}


推荐答案

有几个型号可供选择依赖承诺并将数据从一个传递到下一个。哪一种最有效取决于您是否只需要下次调用中的先前数据,或者是否需要访问所有先前数据。以下是几种型号:

There are a few models for dependent promises and passing data from one to the next. Which one works best depends upon whether you only need the previous data in the next call or whether you need access to all prior data. Here are several models:

callhttp(url1, data1).then(function(result1) {
     // result1 is available here
     return callhttp(url2, data2);
}).then(function(result2) {
     // only result2 is available here
     return callhttp(url3, data3);
}).then(function(result3) {
     // all three are done now, final result is in result3
});



将中间结果分配到更高的范围



Assign Intermediate Results to Higher Scope

var r1, r2, r3;
callhttp(url1, data1).then(function(result1) {
     r1 = result1;
     return callhttp(url2, data2);
}).then(function(result2) {
     r2 = result2;
     // can access r1 or r2
     return callhttp(url3, data3);
}).then(function(result3) {
     r3 = result3;
     // can access r1 or r2 or r3
});



在一个对象中累积结果



Accumulate Results in One Object

var results = {};
callhttp(url1, data1).then(function(result1) {
     results.result1 = result1;
     return callhttp(url2, data2);
}).then(function(result2) {
     results.result2 = result2;
     // can access results.result1 or results.result2
     return callhttp(url3, data3);
}).then(function(result3) {
     results.result3 = result3;
     // can access results.result1 or results.result2 or results.result3
});



Nest,因此可以访问所有以前的结果



Nest, so all Previous Results Can Be Accessed

callhttp(url1, data1).then(function(result1) {
     // result1 is available here
     return callhttp(url2, data2).then(function(result2) {
         // result1 and result2 available here
         return callhttp(url3, data3).then(function(result3) {
             // result1, result2 and result3 available here
         });
     });
})



打破链条进入独立片段,收集结果



如果链的某些部分可以独立进行,而不是一个接一个地进行,那么你可以单独启动它们并使用 Promise.all()知道这些多件作品何时完成,然后你将获得这些独立作品的所有数据:

Break the Chain into Independent Pieces, Collect Results

If some parts of the chain can proceed independently, rather than one after the other, then you can launch them separately and use Promise.all() to know when those multiple pieces are done and you then will have all the data from those independent pieces:

var p1 = callhttp(url1, data1);
var p2 = callhttp(url2, data2).then(function(result2) {
    return someAsync(result2);
}).then(function(result2a) {
    return someOtherAsync(result2a);
});
var p3 = callhttp(url3, data3).then(function(result3) {
    return someAsync(result3);
});
Promise.all([p1, p2, p3]).then(function(results) {
    // multiple results available in results array
    // that can be processed further here with
    // other promises
});



在ES7中等待的序列



由于承诺链只是一种排序异步操作的机制,在ES7中,您还可以使用等待然后使用中间件结果都在相同的范围内(可能比链式 .then()处理程序的单独范围更简单):

Sequence with await in ES7

Since the promise chain is just a mechanism for sequencing asynchronous operations, in ES7, you can also use await and then the intermediate results are all available in the same scope (perhaps simpler than the separate scopes of the chained .then() handlers):

async function someFunction(...) {

    const r1 = await callhttp(url1, data1);

    // can use r1 here to formulate second http call
    const r2 = await callhttp(url2, data2);

    // can use r1 and r2 here to formulate third http call
    const r3 = await callhttp(url3, data3);

    // do some computation that has access to r1, r2 and r3
    return someResult;
}

someFunction(...).then(result => {
    // process final result here
}).catch(err => {
    // handle error here
});

这篇关于如何使用Promises链接和分享先前的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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