Hai,
Saat menggunakan map(...) apakah ada cara saat menangani kesalahan yang dipancarkan dari fungsi iteratee untuk menentukan berapa banyak item yang belum diproses dari koleksi yang disediakan?
Saya menggunakan map
untuk melakukan beberapa permintaan HTTP keluar (menggunakan perpustakaan node request
) untuk larik urlsparams yang berbeda, dll. Sebagian dari permintaan ini saya mungkin mendapatkan kesalahan tertentu dari server target yang dapat saya tangani, tetapi saya kemudian ingin memproses ulang item saat ini yang sedang dikerjakan dan kemudian item yang tersisa yang map
belum diambil.
Saya bertanya-tanya tentang mungkin mengatur bendera pada setiap item dalam koleksi saya yang telah berhasil dikerjakan (tanpa kesalahan), dan kemudian ketika kesalahan dipancarkan yang saya minati, tangani dengan tepat. Kemudian mungkin buat larik baru dari item dengan flag disetel ke false untuk yang belum diproses dan lakukan map
lebih lanjut di atasnya, pastikan saya memanggil panggilan balik terakhir asli dari peta asli.
Tidak yakin apakah ini masuk akal, tetapi apakah ada cara untuk mencapai apa yang saya jelaskan di atas?
Hai @parky128 , terima kasih atas pertanyaannya!
Apakah membungkus iteratee
dengan reflect
berfungsi? reflect
selalu meneruskan objek hasil ke callback
, jadi meskipun salah satu dari iteratee
fungsi kesalahan, map
akan selesai. Kemudian Anda bisa mengulangi objek results
dari map
, memeriksa mana yang memiliki properti error
, dan kemudian menanganinya dengan tepat. Anda tidak perlu memproses ulang item apa pun yang mungkin tidak diambil oleh map
.
async.map(coll, async.reflect(function(val, callback) {
// your request code
}, function(err, results) {
// err will always be null now
results.forEach(function(result, i) {
if (result.error) {
// your code for handling errors
// if `coll` is an array, you could access the value that caused
// this error through `coll[i]` as `map` preserves the order for arrays
} else {
// otherwise `result.value` will contain the result of that `iteratee` call
}
});
});
Jika tidak, untuk menjawab pertanyaan Anda, map
selalu mengembalikan array
. Anda dapat mengulangi array itu dan memeriksa nilai mana yang undefined
. Itu akan sesuai dengan item yang salah, meneruskan undefined
ke callback
, sedang berlangsung saat error
terjadi atau belum dimulai. Pendekatan reflect
mungkin merupakan opsi yang lebih aman, karena undefined
mungkin merupakan hasil yang valid dari panggilan iteratee
.
Terima kasih telah meluangkan waktu untuk menawarkan solusi potensial. Saya sebenarnya ingin panggilan balik akhir async.map dipanggil segera setelah salah satu dari kesalahan fungsi iteratee
dengan kasus kesalahan tertentu yang ingin saya tangkap.
Melihat dokumen yang saya lihat saya dapat mencapai ini dengan meneruskan kesalahan ke fungsi panggilan balik iteratee, tetapi saya bertanya-tanya apakah dalam panggilan balik terakhir yang akan dipanggil async.map, apakah saya bisa menggunakan objek hasil itu untuk membandingkan dengan yang asli koleksi dan lihat apa yang tersisa untuk diproses.
Saya hanya tidak ingin async.map mencoba memproses permintaan lain segera setelah salah satu dari ini mengembalikan kasus kesalahan yang saya minati.
Saya hanya tidak ingin async.map mencoba memproses permintaan lain segera setelah salah satu dari ini mengembalikan kasus kesalahan yang saya minati.
Dengan asumsi iteratee
tidak sinkron, async.map
akan mulai memproses semua item saat panggilan balik terakhir dipanggil. Anda berpotensi dapat membandingkan objek hasil dengan koleksi untuk melihat item mana yang belum selesai diproses, tetapi itu juga memiliki gotcha. Misalnya, Anda harus melakukannya secara serempak, pada saat yang sama panggilan balik terakhir dipanggil, karena objek hasil akan diperbarui sebagai iteratee
s resolve.
Anda dapat mencoba mapSeries
. mapSeries
hanya akan menjalankan satu permintaan dalam satu waktu. yaitu hanya memanggil item berikutnya ketika yang saat ini selesai diproses (sebagai lawan memulai semuanya sekaligus). Ini berarti ketika kesalahan terjadi, dan panggilan balik terakhir dipanggil, tidak ada lagi iteratee
s yang akan dijalankan. Anda kemudian dapat membandingkan hasilnya dengan koleksi untuk melihat item mana yang belum diproses. Ini masih sedikit solusi, tetapi lebih baik daripada menggunakan async.map
. Kelemahan utama dari pendekatan ini adalah bahwa permintaan tidak lagi ditangani secara paralel.
Misalnya, jika koleksi Anda adalah array
async.mapSeries(coll, function(val, callback) {
// your iteratee function
}, function(err, results) {
if (err) {
// unprocessItems will include the item that errored.
var unprocessItems = coll.slice(results.length - 1);
// handle the unprocessedItems
}
});
Hmm Ok, ya fungsi iteratee saya tidak sinkron karena menggunakan perpustakaan permintaan untuk membuat permintaan http keluar dan saya memanggilnya kembali dengan hasilnya. Jadi jika saya mengatakan memiliki 10 item untuk diulang, 4 berhasil dan yang ke-5 gagal yang kemudian akan saya panggil kembali ke fungsi iteratee dengan param kesalahan, jika itu berarti objek hasil dalam panggilan balik terakhir ke async.map hanya akan berisi 4 hasil yang berhasil?
Jika ya maka untuk saat ini saya akan hidup dengan kenyataan bahwa itu masih akan membuat semua panggilan keluar. Saya mungkin akan menjadi saya untuk membagi array saya menjadi array yang lebih kecil dan melakukan async.maps yang lebih kecil dalam mapSeries untuk meminimalkan hit awal ke server target yang diminta.
@hargasinski - Saya akhirnya menggunakan pendekatan async.reflect
dan ini bekerja dengan baik untuk saya, memberi saya visibilitas penuh dari semua item yang memberikan kesalahan :+1:
Terima kasih!
Komentar yang paling membantu
Hai @parky128 , terima kasih atas pertanyaannya!
Apakah membungkus
iteratee
denganreflect
berfungsi?reflect
selalu meneruskan objek hasil kecallback
, jadi meskipun salah satu dariiteratee
fungsi kesalahan,map
akan selesai. Kemudian Anda bisa mengulangi objekresults
darimap
, memeriksa mana yang memiliki propertierror
, dan kemudian menanganinya dengan tepat. Anda tidak perlu memproses ulang item apa pun yang mungkin tidak diambil olehmap
.Jika tidak, untuk menjawab pertanyaan Anda,
map
selalu mengembalikanarray
. Anda dapat mengulangi array itu dan memeriksa nilai mana yangundefined
. Itu akan sesuai dengan item yang salah, meneruskanundefined
kecallback
, sedang berlangsung saaterror
terjadi atau belum dimulai. Pendekatanreflect
mungkin merupakan opsi yang lebih aman, karenaundefined
mungkin merupakan hasil yang valid dari panggilaniteratee
.