Сохраняйте значения только из Promises, которые разрешают и игнорируют отклоненные

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

Promise.all не для этого случая, так как он требует разрешения всех promises.

Promise.some() не то, что я хочу, так как я заранее не знаю, сколько будет promises.

Promise.any() совпадает с Promise.some() с номером 1.

Как этот случай может быть решен? Я использую реализацию Bluebird.

Ответ 1

Конечно, вам повезло, что bluebird уже делает это:

Promise.settle(arrayOfPromises).then(function(results){
    for(var i = 0; i < results.length; i++){
        if(results[i].isFulfilled()){
           // results[i].value() to get the value
        }
    }
});

Вы также можете использовать новый вызов reflect:

Promise.all(arrayOfPromises.map(function(el){ 
    return el.reflect(); 
})).filter(function(p){ 
    return p.isFulfilled();
}).then(function(results){
    // only fulfilled promises here
});

Ответ 2

это то же самое, что и решение @Benjamin, но с более элегантным манипуляцией массивом:

этот код будет игнорировать результат отклоненного обещания, поэтому вы можете запустить 10 promises и получить результаты как массив из 3 элементов:

Promise.settle(arrayOfPromises).then(function(results){
    return results.filter(function (result) {
               return result.isFulfilled();
            }).map(function (result) {
               return result.value();
            });   
}).then(function(results){
     console.log("here you go:", results);
});

здесь проигнорирует отклоненное обещание, но поместит null как результат, поэтому, если вы запустите 10 promises, у вас будут результаты в виде массива из 10 элементов, отклоненное значение будет равно null:

Promise.settle(arrayOfPromises).then(function(results){
    return results.map(function (result) {
               return result.isFulfilled()? result.value() : null;
            }); 
}).then(function(results){
     console.log("here you go:", results);
});