Async: Cara untuk menentukan item yang belum diproses dari async.map() setelah kesalahan dipancarkan

Dibuat pada 10 Jul 2017  ·  5Komentar  ·  Sumber: caolan/async

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?

question

Komentar yang paling membantu

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 .

Semua 5 komentar

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!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat