MDN mengatakan for await...of
memiliki dua kasus penggunaan:
The
for await...of
pernyataan menciptakan loop iterasi async iterable objek serta pada iterables sync, ...
Saya sebelumnya mengetahui yang pertama: async iterables using Symbol.asyncIterator
. Tapi saya sekarang tertarik pada yang terakhir: iterables sinkron.
Kode berikut ini berulang di atas iterable sinkron - sebuah array janji. Tampaknya untuk memblokir proses pada pemenuhan setiap janji.
async function asyncFunction() {
try {
const happy = new Promise((resolve)=>setTimeout(()=>resolve('happy'), 1000))
const sad = new Promise((_,reject)=>setTimeout(()=>reject('sad')))
const promises = [happy, sad]
for await(const item of promises) {
console.log(item)
}
} catch (err) {
console.log(`an error occurred:`, err)
}
}
asyncFunction() // "happy, an error occurred: sad" (printed in quick succession, after about 5 seconds)
Perilaku ini tampaknya sama dengan menunggu setiap janji pada gilirannya, sesuai dengan logika yang ditunjukkan di bawah ini. Apakah pernyataan ini benar?
Saya bertanya karena pola kode ini memiliki jebakan penolakan tersirat Promise.all
dan Promise.allSettled
menghindarinya, dan sepertinya aneh bagi saya bahwa pola ini akan didukung secara eksplisit oleh bahasa.
sumber
for await... of
dengan iterables sinkron, benar, dan jika demikian, apakah penting bahwa pola itu dapat memancarkan kesalahan penolakan yang tidak ditangani?Jawaban:
Ya, ini aneh, dan Anda seharusnya tidak melakukan ini. Jangan mengulangi susunan janji, itu justru mengarah pada masalah penolakan-ditangani yang Anda sebutkan .
Jadi mengapa ini didukung dalam bahasa? Untuk melanjutkan semantik janji yang ceroboh.
Anda dapat menemukan alasan yang tepat dalam komentar tentang masalah yang membahas bagian proposal ini :
sumber
unhandledrejection
acara?window.addEventListener('unhandledrejection',...
Singkatnya: itu adalah satu-satunya contoh yang bisa saya ingatkan, dari jenis emisi kesalahan oleh JavaScript. Saya hampir pasti salah untuk memikirkan ini. Akhirnya: apakah emisi "kesalahan" ini benar-benar penting selain memiliki pesan kesalahan yang tidak diinginkan di konsol?The
sad
janji tidak menjadiawait
ed ketika gagal - bahwa kebutuhan kode untuk menyelesaikan menungguhappy
sebelum dapat mulai menunggusad
. Thesad
Janji gagal sebelumhappy
resolve. (Promise.all
adalah alat yang lebih cocok untuk kasus penggunaan ini)sumber
Promise.all
ini merupakan solusi yang lebih baik, mengapa bahasa tersebut memenuhi sintaksis ini?for await...of
bisa dengan mudah diimplementasikan untuk hanya menghitung iterables asynchronous. Tapi mereka melayani untuk menghitung iterables sinkron (tetapi dengan perangkap (tampak?)). Mengapa?for await ... of
menerima iterables sinkron? Saya membayangkan mendukung generator async yang secara kondisional dapat mengembalikan item sinkron.