запрос-обещание l oop, как включить данные запроса, отправленные с ответом? - PullRequest
0 голосов
/ 13 апреля 2020

Я пытаюсь использовать запрос-обещание в al oop, а затем отправить ответ обратно клиенту со всеми ответами. Приведенный ниже код работает, однако я хочу также включить данные запроса в каждый ответ, чтобы идентификатор запроса можно было сопоставить с результатом. Есть ли встроенный способ сделать это:

promiseLoop: function (req, res) {
    var ps = [];
    for (var i = 0; i < 3; i++) {
        // var read_match_details = {
        //     uri: 'https://postman-echo.com/get?foo1=bar1&foo2=bar2',
        //     json: true // Automatically parses the JSON string in the response 
        // };
        var session = this.sessionInit(req, res);
        if (this.isValidRequest(session)) {
            var assertion = session.assertions[i];
            const options = {
                method: 'POST',
                uri: mConfig.serviceURL,
                body: assertion,
                headers: {
                    'User-Agent': 'aggregator-service'
                },
                json: true
            }
            logger.trace(options);
            ps.push(httpClient(options));
        }

    }

    Promise.all(ps)
        .then((results) => {
            console.log(results); // Result of all resolve as an array
            res.status(200);
            res.send(results);
            res.end();
        }).catch(err => console.log(err));  // First rejected promise
}

1 Ответ

0 голосов
/ 13 апреля 2020

Предполагая, что httpClient() - это request-promise, на который вы ссылаетесь, а значение assertion - это то, что вы пытаетесь передать с этим результатом, вы можете изменить это:

ps.push(httpClient(options));

на это :

ps.push(httpClient(options).then(result => {
    return {id: assertion, result};
}));

Тогда ваше обещание будет разрешено для этого объекта, который содержит и результат, и идентификатор, и вы сможете получить доступ к каждому из них в конечном массиве результатов.


Ваш код не показывает, каков текущий результат. Если это уже объект, вы также можете просто добавить свойство id к этому объекту, если хотите. Это зависит от вас, как именно вы сложите этот окончательный результат.

ps.push(httpClient(options).then(result => {
    // add id into final result
    result.id = assertion;
    return result;
}));

В любом случае, общая идея заключается в том, что перед помещением обещания в массив, вы используете обработчик .then() для небольшого изменения возвращаемого значения. результат, добавляя любые данные, которые вы хотите добавить, и затем возвращая этот новый измененный результат, чтобы он стал разрешенным значением цепочки обещаний.


Чтобы убедиться, что вы обрабатываете все ответы, даже если некоторые имеют ошибка, вы можете использовать более новую [Promise.allSettled()][1] вместо Promise.all(), а затем посмотреть, какие ответы удалось или не удалось обработать результаты. Или вы можете отследить любые ошибки, превратить их в разрешенные обещания, но дать им чувственное значение (часто null), которое вы можете увидеть при обработке окончательных результатов:

ps.push(httpClient(options).then(result => {
    // add id into final result
    result.id = assertion;
    return result;
}).catch(err => {
    console.log(err);
    // got an error, but don't want Promise.all() to stop
    // so turn the rejected promise into a resolved promise
    // that resolves to an object with an error in it
    // Processing code can look for an `.err` property.
    return {err: err};
}));

Затем, позже в вашем код обработки:

Promise.all(ps)
    .then((results) => {
        console.log(results); // Result of all resolve as an array

        // filter out error responses
        let successResults = results.filter(item => !item.err);
        res.send(successResults );
    }).catch(err => console.log(err));  // First rejected promise
...