Разрешите обещания в последовательности и вернитесь к первому, которое выполнится - PullRequest
0 голосов
/ 20 октября 2019

Я использую Q библиотеку обещаний. Приведенный ниже код выполняет два вызова службы параллельно и ожидает первого результата, который возвращается до истечения времени ожидания. Я хочу изменить его так, чтобы он выполнял последовательные вызовы службы и возвращал результат успешного вызова службы, если в любом последовательном вызове службы происходит сбой, затем переходите к следующему вызову службы, пока какой-либо из них не будет успешным. Я хочу достичь этого без использования async / await.

return Q.any([
    service1.getUser(username).catch(saveError(‘getUserCall’)), // SERVICE CALL 1
    service2.getUserDetails(username).catch(saveError(‘getUserDetailsCall’)) // SERVICE CALL 2
])
.timeout(SEARCH_TIMEOUT)
.catch(handleErrors);

function handleErrors() {
    var err = new Error('Unable to find user  ' + username);
    err.statusCode = 404;
    return Q.reject(err);
}

function saveError(requestName) {
    return function(err) {
        errors[requestName] = err;
        return Q.reject(err);
    };
}

После исследования в Интернете я обнаружил, что это может быть достигнуто с помощью Reduce, однако, когда первый вызов службы не удался, он не выполнил второй вызов службы.

var getUserCalls = [
    function(username) {
        return service1.getUser(username).catch(
            function() {
                saveError('‘getUserCall’');
            }
        );
    },
    function(username) {
        return service2.getUserDetails(username).catch(
            function(err) {
                saveError('‘getUserDetailsCall’');
                return Q.reject(err);
            }
        );
    }
];

return getUserCalls.reduce(function(curr, next) {
    return curr.then(function(result) {
        return !result || !result.username ? next(username) : result;
    });
}, Q({}))
    .timeout(SEARCH_TIMEOUT)
    .catch(handleErrors);
...