Рекомендуемый способ выполнить несколько параллельных вызовов REST и дождаться всех результатов в файле node.js. - PullRequest
0 голосов
/ 27 октября 2019

Я хочу вызвать несколько API REST для получения данных, которые я использую. Я хочу, чтобы все вызовы REST завершились, а затем выполнили некоторые вычисления. Код ниже работает, но мне это не очень нравится. Особенно, когда один сайт возвращает ошибку, не так легко увидеть, откуда она появилась. Я бы предпочел обрабатывать каждый звонок отдельно, а затем в конце «ждать», чтобы все звонки завершились. Таким образом, я мог бы также выполнить частичное вычисление, если каким-то образом один вызов REST не работал

const rp = require('request-promise');


var site1 = {
    uri: 'https://www.site1.com/api/v1/somedata.json',
    json: true
};


var site2 = {
    uri: 'https://www.site2.com/api/v1/somedata.json',
    json: true
};

var site3 = {
    uri: 'https://www.site3.com/api/v1/somedata.json',
    json: true
};


var promises = [];
promises.push(rp(site1));
promises.push(rp(site2));
promises.push(rp(site3));


Promise.all(promises).then(data => {
    console.log(data);
    // fetch all data from data variable and do calulation 
}, err => {
    console.log('error')
});

1 Ответ

1 голос
/ 27 октября 2019

Если вы хотите обрабатывать каждый из них по отдельности при получении результатов, вы можете добавить обработчик .then() и / или .catch() для каждого из них:

var promises = [];
promises.push(rp(site1).then(result => {
    // do any partial processing
    return result;
}).catch(err => {
    // decide what to do if error
    throw err;
}));
promises.push(rp(site2).then(result => {
    // do any partial processing
    return result;
}).catch(err => {
    // decide what to do if error
    throw err;
}));
promises.push(rp(site3).then(result => {
    // do any partial processing
    return result;
}).catch(err => {
    // decide what to do if error
    throw err;
}));

Promise.all(promises).then(data => {
    console.log(data);
    // fetch all data from data variable and do calulation 
}, err => {
    console.log('error')
});

Конечно, если обработкаидентичен для каждого запроса, затем инкапсулирует эту дополнительную функциональность в функцию, которая вызывает rp(), а затем выполняет обработку, и затем вы можете использовать эту функцию вместо rp(). Таким образом, это действительно зависит от того, какую именно промежуточную обработку вы хотите выполнить.


Если обработка идентична, вы можете создать свою собственную функцию-обертку. Например, если вы хотите, чтобы обработка продолжалась, даже если произошла ошибка, вы можете сделать это:

function rpExtra(args) {
    return rp(args).catch(err => {
        console.log(err);
        return null;   // sentinel resolved value to keep processing going for Promise.all()
    });
}

var promises = [];
promises.push(rpExtra(site1));
promises.push(rpExtra(site2));
promises.push(rpExtra(site3));


Promise.all(promises).then(data => {
    console.log(data);
    // fetch all data from data variable and do calculation
    // skip any `null` values (those had errors) 
}, err => {
    console.log('error')
});

Подробности того, что именно нужно сделать для обработки ошибок, очень специфичны для конкретной ситуации, поэтому ядали вам структуру, и вам нужно будет указать, что именно вы хотите сделать. Обработчик .catch() может либо перебросить (чтобы отклонить обещание и иметь отмену Promise.all()), либо вернуть значение (чтобы изменить обещание на разрешенное и продолжить обработку Promise.all()).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...