By user1513388


2015-02-25 08:25:34 8 Comments

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

1 comments

@jfriend00 2015-02-25 08:58:21

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:

Feed Result of One to the Next

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

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

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

@user1513388 2015-02-25 09:33:59

Thank you very much - I'll try these now!

@Bergi 2015-02-25 09:44:17

The latter two solutions are also discussed here

@user1513388 2015-02-25 14:21:41

Worked perfectly thanks.

@Anthony 2015-06-19 04:23:14

Perfect code for fun and profit.

@jfriend00 2017-10-27 04:53:55

@TravisBear - callhttp can be any asynchronous operation that returns a promise that is resolved or rejected when the async operation is done. There's an implementation of it in the original question here that this answer is based on, but it can be any async operation that returns a promise.

@jfriend00 2018-04-10 02:44:25

Added an option to use await in ES7.

@oldboy 2019-10-28 21:27:31

very instructive post. ty

Related Questions

Sponsored Content

94 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6267768 View
  • 7828 Score
  • 94 Answer
  • Tags:   javascript arrays

42 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

37 Answered Questions

[SOLVED] How do I return the response from an asynchronous call?

58 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

56 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

65 Answered Questions

[SOLVED] How do I check whether a checkbox is checked in jQuery?

86 Answered Questions

[SOLVED] How do JavaScript closures work?

4 Answered Questions

58 Answered Questions

[SOLVED] How do I redirect to another webpage?

17 Answered Questions

Sponsored Content