Sejauh yang saya mengerti, dalam ES7 / ES2016 menempatkan multiple await
dalam kode akan bekerja sama dengan chaining .then()
dengan janji, yang berarti bahwa mereka akan mengeksekusi satu demi satu daripada di parallerl. Jadi, misalnya, kami memiliki kode ini:
await someCall();
await anotherCall();
Apakah saya memahaminya dengan benar yang anotherCall()
akan dipanggil hanya ketika someCall()
selesai? Apa cara paling elegan untuk memanggil mereka secara paralel?
Saya ingin menggunakannya di Node, jadi mungkin ada solusi dengan pustaka async?
EDIT: Saya tidak puas dengan solusi yang disediakan dalam pertanyaan ini: Perlambatan karena janji yang tidak paralel menunggu di generator async , karena menggunakan generator dan saya bertanya tentang kasus penggunaan yang lebih umum.
javascript
node.js
asynchronous
ecmascript-6
babeljs
Victor Marchuk
sumber
sumber
await
akan menunggu fungsi pertama untuk menyelesaikan seluruhnya sebelum menjalankan yang kedua.Promise
. Pertanyaan terkait adalah tentang perpustakaan burung biru dengan generator & hasil. Secara konseptual serupa mungkin, tetapi tidak dalam implementasi.Jawaban:
Anda bisa menunggu di
Promise.all()
:Untuk menyimpan hasilnya:
Perhatikan bahwa
Promise.all
gagal dengan cepat, yang berarti bahwa begitu salah satu janji yang diberikan kepadanya ditolak, maka semuanya ditolak.Sebaliknya, jika Anda ingin menunggu semua janji untuk dipenuhi atau ditolak, maka Anda dapat menggunakannya
Promise.allSettled
. Perhatikan bahwa Internet Explorer tidak mendukung metode ini.sumber
[result1, result2] = Promise.all([async1(), async2()]);
= await Promise.all
?TL; DR
Gunakan
Promise.all
untuk panggilan fungsi paralel, perilaku jawaban tidak benar ketika kesalahan terjadi.Pertama, jalankan semua panggilan asinkron sekaligus dan dapatkan semua
Promise
objek. Kedua, gunakanawait
padaPromise
objek. Dengan cara ini, selagi Anda menunggu yang pertamaPromise
untuk menyelesaikan panggilan asinkron lainnya masih berlangsung. Secara keseluruhan, Anda hanya akan menunggu selama panggilan asinkron paling lambat. Sebagai contoh:Contoh JSbin: http://jsbin.com/xerifanima/edit?js,console
Peringatan: Tidak masalah jika
await
panggilan berada di jalur yang sama atau di jalur yang berbeda, selamaawait
panggilan pertama terjadi setelah semua panggilan tidak sinkron. Lihat komentar JohnnyHK.Pembaruan: jawaban ini memiliki waktu yang berbeda dalam penanganan kesalahan sesuai dengan jawaban @bergi , ia TIDAK membuang kesalahan saat kesalahan terjadi tetapi setelah semua janji dijalankan. Saya membandingkan hasilnya dengan tip @ jonny:,
[result1, result2] = Promise.all([async1(), async2()])
periksa cuplikan kode berikutsumber
[someResult, anotherResult] = [await someResult, await anotherResult]
jika Anda mengubahconst
kelet
.await
pernyataan berurutan, kan? Artinya, eksekusi berhenti sampai yang pertamaawait
selesai, lalu pindah ke yang kedua.Promise.all
dijalankan secara paralel.Promise.all
. Jika setiap permintaan adalah panggilan jaringan,await someResult
harus diselesaikan sebelumawait anotherResult
dimulai. Sebaliknya, dalamPromise.all
duaawait
panggilan dapat dimulai sebelum salah satu diselesaikan.Memperbarui:
Jawaban asli menyulitkan (dan dalam beberapa kasus tidak mungkin) untuk menangani penolakan janji dengan benar. Solusi yang benar adalah dengan menggunakan
Promise.all
:Jawaban asli:
Pastikan Anda memanggil kedua fungsi sebelum menunggu salah satunya:
sumber
await
kemudian akan mengatasinya menjadi nilai aktual.Ada cara lain tanpa Promise.all () untuk melakukannya secara paralel:
Pertama, kami memiliki 2 fungsi untuk mencetak angka:
Ini berurutan:
Ini paralel:
sumber
Ini dapat dilakukan dengan Promise.allSettled () , yang mirip dengan
Promise.all()
tetapi tanpa perilaku gagal-cepat.Catatan : Ini adalah fitur tepi berdarah dengan dukungan browser terbatas, jadi saya sangat menyarankan untuk memasukkan polyfill untuk fungsi ini.
sumber
Saya telah membuat intisari pengujian beberapa cara berbeda untuk menyelesaikan janji, dengan hasil. Mungkin bermanfaat untuk melihat opsi yang berfungsi.
sumber
Meskipun pengaturan p1, p2 dan p3 tidak sepenuhnya menjalankannya secara paralel, mereka tidak menahan eksekusi apa pun dan Anda dapat menjebak kesalahan kontekstual dengan tangkapan.
sumber
Dalam kasus saya, saya memiliki beberapa tugas yang ingin saya jalankan secara paralel, tetapi saya perlu melakukan sesuatu yang berbeda dengan hasil dari tugas-tugas itu.
Dan hasilnya:
sumber
menunggu Promise.all ([someCall (), anotherCall ()]); seperti yang sudah disebutkan akan bertindak sebagai pagar benang (sangat umum dalam kode paralel sebagai CUDA), maka itu akan memungkinkan semua janji di dalamnya untuk berjalan tanpa saling menghalangi, tetapi akan mencegah eksekusi untuk melanjutkan sampai SEMUA diselesaikan.
pendekatan lain yang layak untuk dibagikan adalah Node.js async yang juga akan memungkinkan Anda untuk dengan mudah mengontrol jumlah konkurensi yang biasanya diinginkan jika tugas terkait langsung dengan penggunaan sumber daya terbatas seperti panggilan API, operasi I / O, dll.
Kredit untuk artikel Sedang autor ( baca selengkapnya )
sumber
Saya memilih:
Waspadai saat Anda memanggil fungsi, itu dapat menyebabkan hasil yang tidak terduga:
Namun mengikuti selalu memicu permintaan untuk membuat Pengguna baru
sumber
else
blok.Saya membuat fungsi pembantu waitAll, mungkin itu bisa membuatnya lebih manis. Ini hanya berfungsi di nodejs untuk saat ini, bukan di browser chrome.
sumber
for
Loop berurutan menanti setiap janji dan menambahkan hasilnya ke array.