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.
I'm calling it like this:
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]);
});
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
This is the callhttp
function:
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 );
}
});
}
Introduction to the JavaScript promise chaining The callback passed to the then() method executes once the promise is resolved. In the callback, we show the result of the promise and return a new value multiplied by two ( result*2 ).
Promise chaining: Promise chaining is a syntax that allows you to chain together multiple asynchronous tasks in a specific order. This is great for complex code where one asynchronous task needs to be performed after the completion of a different asynchronous task.
Promises themselves do not need threads in order to do that. They are objects that essentially provide bookkeeping for asynchronous operations - keeping state flags, result values and listeners for a state transition. These are all things that can easily be done with regular single threaded Javascript.
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
});
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
});
});
})
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
});
await
in ES7Since 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
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With