我正在使用bluebird库,需要发出一系列HTTP请求,并且需要对下一个HTTP请求的某些响应数据。我建立了一个函数来处理我的请求callhttp()。这需要一个URL和POST的正文。
callhttp()
我这样称呼它:
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功能:
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 ); } }); }
有一些模型用于从属承诺并将数据从一个传递到另一个。哪种方法效果最好取决于您是在下一个呼叫中仅需要先前的数据,还是需要访问所有先前的数据。以下是几种型号:
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 });
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 });
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 }); }); })
如果链中的某些部分可以独立进行,而不是一个接一个地进行,那么您可以分别启动它们,并使用它们Promise.all()来了解何时完成了这多个部分,然后您将获得这些独立部分中的所有数据:
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 });
await
由于promise链只是一种用于对异步操作进行排序的机制,因此在ES7中,您还可以使用await,然后中间结果都可以在同一作用域中使用(也许比链接.then()处理程序的单独作用域更简单):
.then()
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 });