Promise.all for Rejections and Resolves

Sliby byly neuvěřitelným doplňkem JavaScriptu; šetří nám peklo zpětného volání, umožňují snadnější údržbu asynchronního kódování a umožňují nám sledovat více asynchronních procesů najednou. Promise.all přichází na mysl, což nám umožňuje reagovat, když bylo vyřešeno několik slibů. Bohužel Promise.all vyřeší se pouze tehdy, když jsou vyřešeny všechny sliby, takže pokud některý ze slibů selže, zobrazí se catch se nazývá místo then:

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

To je problém, pokud chcete, aby byly stejné funkce provedeny bez ohledu na to, zda bude odmítnut jakýkoli příslib v poli. Stejnou funkci můžete poskytnout then a catch ale to by mohlo vést k problémům s údržbou a občasným „WTF IS THIS?!“ komentáře od jiných inženýrů.

Co bychom tedy měli dělat, když chceme Promise.all spustit funkci bez ohledu na jakékoli odmítnutí? Jake Archibald má odpověď:

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

Každý příslib je catch zpětné volání vrací undefined což umožňuje, aby se selhání slibu považovalo za úspěch. Chcete-li dokázat, že to funguje, zvažte tento úryvek:

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!

Přestože byl druhý příslib zamítnut, Promise.all then je nazýván! V budoucnu budeme moci používat Promise.prototype.finally snadněji zvládnout úspěch a neúspěch.

Děkuji Jakeovi za tento úžasný trik!