Как связать и поделиться предыдущими результатами с помощью Promises

Я использую библиотеку bluebird и вам нужно сделать серию HTTP-запросов, а некоторые данные ответа будут переданы в следующий HTTP-запрос. Я создал функцию, которая обрабатывает мои запросы, называемые callhttp(). Это занимает URL-адрес и тело POST.

Я называю это следующим образом:

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

Ответ 1

Существует несколько моделей для зависимого promises и передачи данных от одного к другому. Какой из них лучше всего работает, зависит от того, нужны ли вам только предыдущие данные в следующем вызове или нужен ли вам доступ ко всем предыдущим данным. Вот несколько моделей:

Результат подачи от одного до следующего

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(), чтобы знать, когда эти несколько частей будут выполнены, и тогда у вас будут все данные из этих независимых части:

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