Promessas foram um acréscimo incrível ao JavaScript; elas nos poupam do inferno do callback, tornam a codificação assíncrona mais fácil de manter e nos permitem acompanhar vários processos assíncronos ao mesmo tempo. Promise.all vem à mente, permitindo-nos reagir quando várias promessas são resolvidas. Infelizmente, o Promise.all só resolve quando todas as promessas são resolvidas, portanto, se alguma das promessas falhar, o catch é chamado em vez do then:



Promise.all([
    Promise.resolve(1),
    Promise.reject(0)
])
.then(() => { console.log('resolved!'); })
.catch(() => { console.log('failed!') });
// >> failed!


Isso é um problema se o senhor quiser que a mesma funcionalidade seja executada independentemente de qualquer promessa no array ser rejeitada. O senhor poderia fornecer a mesma função para then e para catch mas isso pode levar a problemas de manutenção e comentários ocasionais do tipo “WTF IS THIS?!” de outros engenheiros.


Então, o que devemos fazer quando queremos Promise.all acione a funcionalidade independentemente de quaisquer rejeições? Jake Archibald tem a resposta:



Promise.all(promises.map(p => p.catch(() => undefined)));


A promessa de cada catch callback de cada promessa retorna undefined o que permite que a falha da promessa seja tratada como sucesso. Para provar que isso funciona, considere este trecho:



Promise.all([
    // Resolves
    Promise.resolve(1), 
    // Rejects after 2 seconds
    new Promise((resolve, reject) => setTimeout(() => reject(1), 2000))
].map(p => p.catch(() => undefined))).then(() => console.log('done!'));

// >> done!


Apesar de a segunda promessa ter sido rejeitada, o Promise.all then é chamado! No futuro, poderemos usar o Promise.prototype.finally para lidar mais facilmente com o sucesso e o fracasso.


Obrigado ao Jake por esse truque incrível!