Javascript 如何通过承诺链接和共享先前的结果

Javascript 如何通过承诺链接和共享先前的结果,javascript,node.js,bluebird,Javascript,Node.js,Bluebird,我正在使用bluebird库,需要发出一系列HTTP请求,并需要向下一个HTTP请求发送一些响应数据。我构建了一个名为callhttp()的函数来处理我的请求。这需要一个url和一篇文章的正文 我这样称呼它: var payload = '{"Username": "joe", "Password": "password"}'; var join = Promise.join; join( callhttp("172.16.28.200", payload), callhttp(

我正在使用bluebird库,需要发出一系列HTTP请求,并需要向下一个HTTP请求发送一些响应数据。我构建了一个名为
callhttp()
的函数来处理我的请求。这需要一个url和一篇文章的正文

我这样称呼它:

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密钥,依此类推。如何从第一个请求中获取响应数据

更新

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

对于依赖承诺和从一个到另一个传递数据,有一些模型。哪种方法最有效取决于您在下一次通话中是否只需要以前的数据,还是需要访问以前的所有数据。以下是几个模型:

将一个的结果馈送到下一个 将中间结果分配到更高的范围 将结果累积到一个对象中 嵌套,以便可以访问以前的所有结果 将链分成独立的部分,收集结果 如果链的某些部分可以独立进行,而不是一个接一个地进行,则您可以单独启动它们,并使用
Promise.all()
了解这些多个部分何时完成,然后您将获得这些独立部分的所有数据:

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中带有
wait
的序列 由于承诺链只是对异步操作进行排序的一种机制,因此在ES7中,您还可以使用
wait
,然后中间结果都可以在同一范围内使用(可能比链式
.then()
处理程序的单独范围更简单):


对于依赖承诺和从一个到另一个传递数据,有一些模型。哪种方法最有效取决于您在下一次通话中是否只需要以前的数据,还是需要访问以前的所有数据。以下是几个模型:

将一个的结果馈送到下一个 将中间结果分配到更高的范围 将结果累积到一个对象中 嵌套,以便可以访问以前的所有结果 将链分成独立的部分,收集结果 如果链的某些部分可以独立进行,而不是一个接一个地进行,则您可以单独启动它们,并使用
Promise.all()
了解这些多个部分何时完成,然后您将获得这些独立部分的所有数据:

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中带有
wait
的序列 由于承诺链只是对异步操作进行排序的一种机制,因此在ES7中,您还可以使用
wait
,然后中间结果都可以在同一范围内使用(可能比链式
.then()
处理程序的单独范围更简单):



是的,bits工作正常,并且它返回了一个承诺,因此连接工作正常。我正在使用请求库并已承诺它。您在问题中显示的对
callhttp()
的三个调用正在并行处理,因此您不能在其他调用中使用任何一个的结果。
callhttp()
是否返回一个承诺?您可以添加
callhttp
函数吗?刚刚添加了
callhttp
函数是的,位工作正常,它返回一个承诺,因此连接工作正常。我正在使用请求库并已承诺。您对
callhttp()的三次调用
您在问题中显示的结果是并行处理的,因此您不能在其他问题中使用其中任何一个的结果。
callhttp()
是否也会返回承诺?能否添加
callhttp
函数?刚刚添加了
callhttp
函数非常感谢-我现在就试试这些!后两种解决方案也在讨论中,非常有效。谢谢。完美的代码带来乐趣和利润。@TravisBear-
callhttp
可以是任何异步操作,该操作返回的承诺在异步操作完成时被解析或拒绝。这个答案基于原始问题中的一个实现,但它可以是任何返回承诺的异步操作。非常感谢-我现在就试试这些!后两种解决方案也在讨论中,非常有效。谢谢。完美的代码带来乐趣和利润。@TravisBear-
callhttp
可以是任何异步操作,该操作返回的承诺在异步操作完成时被解析或拒绝。这个答案所基于的原始问题中有一个实现,但它可以是任何返回承诺的异步操作。
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
});
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
         });
     });
})
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
});
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
});