Promise.any делаем это правильно


В EcmaScript 6 появилось много новых вкусностей. Среди них промисы, которые значительно облегчают жизнь. Но когда нужно выполнить параллельно несколько промисов стандартными средствами сделать это только через Promise.all(...) и Promise.race(...). Этого явно недостаточно для комфортной работы.



Для начала разберемся с тем что есть:

Promise.all реализует семантику логического асинхронного AND - то есть все промисы должны вернуть TRUE (resolve), и только тогда вызовется .then(...). Если-же хоть один промис вернул FALSE (reject), то выполнение пойдет по ветке .catch(...)

Promise.race - тут все еще проще. Результатом этого промиса будет результат самого быстрого промиса из тех, что переданы в качестве его параметров.

Выбор не богатый.

А что делать если нам нужна семантика ANY - то есть необходим чтобы хотя-бы один из промисов вернул результат. А reject был только тогда, когда все помисы вернули FALSE.

В сети можно найти реализаци Promise.any. К минусам именно этой реализации относится то, что промису все равно нужно ждать выполнение всех остальных промисов, чтобы понять какой метод вызвать далее. Если у нас ситуация, когда нам нужен только один, первый, результат (что бывает очень часто), или оповещение о том, что все промисы зафейлились, то можно использовать такое решение:

Promise.any = function(arrayOfPromises){
    var failed = [];
    return new Promise((resolve, reject)=>{
        arrayOfPromises.forEach(promise => {
        // как только промис будет выполнен
            promise.then(result => {
        // вернуть результат выполнения самого быстрого
                resolve(result);
            })
        // если промис вернул ошибку,
            .catch(err => {
        // то собираем результат и
                failed.push(err);
        // если это последний
                if (failed.length == arrayOfPromises.length){
        // возвращаем ошибку
                    reject(new Error('All return false:'+failed));
                }
            });
        })
    });
};

Поскольку промис сохраняет свое состояние, то результатом выполнения этого промиса будет результат самого быстрого из массива промисов и только он. Все остальные результаты будут проигнорированы. Если Нужны все результаты всех успешных промисов, то можно воспользоваться реализацией по ссылке выше.

Комментарии

Популярные сообщения из этого блога

Алгоритм NEAT. Эволюционирующие нейронные сети возрастающих топологий.

Цепи Маркова простыми словами. Пишем пирожки.