Como encadear e compartilhar resultados anteriores com Promises

Estou usando a biblioteca bluebird e preciso fazer uma série de solicitações HTTP e preciso de alguns dos dados de resposta para a próxima solicitação HTTP. Eu construí uma function que lida com meus pedidos chamados callhttp() . Isso leva um URL e o corpo de um POST.

Eu estou chamando assim:

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

A primeira solicitação obtém uma chave de API que precisa ser passada para a segunda solicitação e assim por diante. Como obter os dados de resposta da primeira solicitação?

ATUALIZAR

Esta é a function 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 ); } }); } 

Existem alguns modelos para promises dependentes e passar dados de um para o outro. Qual deles funciona melhor depende se você só precisa dos dados anteriores na próxima chamada ou se você precisa acessar todos os dados anteriores. Aqui estão vários modelos:

Feed resultado de um para o próximo

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

Atribuir Resultados Intermediários ao Escopo Mais Alto

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

Acumule os resultados em um 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, para que todos os resultados anteriores possam ser acessados

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

Quebre a corrente em pedaços independentes, colete os resultados

Se algumas partes da cadeia puderem prosseguir de forma independente, em vez de uma após a outra, você poderá iniciá-las separadamente e usar Promise.all() para saber quando essas várias partes são feitas e então você terá todos os dados dessas partes independentes :

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

Sequência com await no ES7

Como a cadeia de promise é apenas um mecanismo para sequenciar operações assíncronas, no ES7, você também pode usar o wait e os resultados intermediários estarão todos disponíveis no mesmo escopo (talvez mais simples que os escopos separados dos manipuladores .then() encadeados):

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