Seperti judulnya. Bagaimana saya melakukan ini?
Saya ingin menelepon whenAllDone()
setelah forEach-loop telah melewati setiap elemen dan melakukan beberapa pemrosesan asinkron.
[1, 2, 3].forEach(
function(item, index, array, done) {
asyncFunction(item, function itemDone() {
console.log(item + " done");
done();
});
}, function allDone() {
console.log("All done");
whenAllDone();
}
);
Mungkinkah bekerja seperti ini? Kapan argumen kedua untuk forEach adalah fungsi callback yang berjalan setelah melewati semua iterasi?
Output yang diharapkan:
3 done
1 done
2 done
All done!
javascript
node.js
asynchronous
callback
Dan Andreasson
sumber
sumber
forEach
metode array standar memilikidone
parameterallDone
panggilan balik dan panggilan balik!Jawaban:
Array.forEach
tidak menyediakan keramahtamahan ini (oh jika itu mau) tetapi ada beberapa cara untuk mencapai apa yang Anda inginkan:Menggunakan penghitung sederhana
(terima kasih kepada @vanuan dan lainnya) Pendekatan ini menjamin bahwa semua item diproses sebelum memanggil callback "selesai". Anda perlu menggunakan penghitung yang diperbarui dalam panggilan balik. Tergantung pada nilai parameter indeks tidak memberikan jaminan yang sama, karena urutan pengembalian operasi asinkron tidak dijamin.
Menggunakan ES6 Janji
(perpustakaan janji dapat digunakan untuk browser lama):
Memproses semua permintaan yang menjamin eksekusi secara sinkron (mis. 1 kemudian 2 kemudian 3)
Memproses semua permintaan async tanpa eksekusi "sinkron" (2 mungkin selesai lebih cepat dari 1)
Menggunakan pustaka async
Ada perpustakaan asinkron lainnya, async menjadi yang paling populer, yang menyediakan mekanisme untuk mengekspresikan apa yang Anda inginkan.
EditIsi pertanyaan telah diedit untuk menghapus kode contoh yang sebelumnya sinkron, jadi saya telah memperbarui jawaban saya untuk menjelaskan. Contoh asli menggunakan kode suka sinkron untuk memodelkan perilaku asinkron, jadi yang berikut ini diterapkan:
array.forEach
adalah sinkron dan begitu jugares.write
, sehingga Anda hanya dapat menempatkan panggilan balik Anda setelah panggilan Anda untuk foreach:sumber
if(index === array.length - 1)
dan hapusitemsProcessed
Jika Anda menjumpai fungsi-fungsi tidak sinkron, dan Anda ingin memastikan bahwa sebelum mengeksekusi kode itu menyelesaikan tugasnya, kami selalu dapat menggunakan kemampuan panggilan balik.
Sebagai contoh:
Catatan:
functionAfterForEach
adalah fungsi yang akan dieksekusi setelah tugas masing-masing selesai.asynchronous
adalah fungsi asinkron yang dijalankan di dalam foreach.sumber
Semoga ini akan memperbaiki masalah Anda, saya biasanya bekerja dengan ini ketika saya perlu menjalankan forEach dengan tugas-tugas asinkron di dalam.
dengan
sumber
Sungguh aneh berapa banyak jawaban yang salah telah diberikan pada kasus asinkron ! Dapat dengan mudah ditunjukkan bahwa memeriksa indeks tidak memberikan perilaku yang diharapkan:
keluaran:
Jika kami memeriksa
index === array.length - 1
, panggilan balik akan dipanggil setelah selesai iterasi pertama, sementara elemen pertama masih tertunda!Untuk mengatasi masalah ini tanpa menggunakan perpustakaan eksternal seperti async, saya pikir cara terbaik Anda adalah menyimpan panjang daftar dan pengurangan jika setelah setiap iterasi. Karena hanya ada satu utas, kami yakin tidak ada kemungkinan kondisi balapan.
sumber
Dengan ES2018 Anda dapat menggunakan async iterators:
sumber
Solusi saya tanpa Janji (ini memastikan bahwa setiap tindakan berakhir sebelum yang berikutnya dimulai):
sumber
sumber
Ini adalah solusi untuk Node.js yang tidak sinkron.
menggunakan paket npm async.
(JavaScript) Sinkronisasi forEach Loop dengan callback di dalamnya
sumber
Solusi saya:
Contoh:
sumber
Saya mencoba Cara Mudah untuk mengatasinya, membagikannya kepada Anda:
request
adalah Fungsi Perpustakaan mssql di Node js. Ini dapat menggantikan setiap fungsi atau Kode yang Anda inginkan. Semoga berhasilsumber
sumber
Anda seharusnya tidak memerlukan panggilan balik untuk mengulang melalui daftar. Tambahkan saja
end()
panggilan setelah pengulangan.sumber
res.write
BUKAN operasi asinkron, jadi kode Anda tidak akan berfungsi.Solusi sederhana akan seperti ikuti
sumber
Bagaimana dengan setInterval, untuk memeriksa jumlah iterasi yang lengkap, membawa jaminan. tidak yakin apakah itu tidak membebani ruang lingkup, tetapi saya menggunakannya dan tampaknya menjadi satu-satunya
sumber