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!