Async: Menyiapkan Penangan Acara menggunakan Async

Dibuat pada 25 Okt 2016  ·  4Komentar  ·  Sumber: caolan/async

Saya mengalami masalah saat menggunakan async di salah satu tes integrasi saya yang melibatkan event handler. Masalahnya adalah event handler perlu diatur (dengan referensi ke callback yang disediakan async) sebelum event dipancarkan. Namun kode event handler membutuhkan panggilan balik tambahan segera.

Berikut adalah contoh sederhana yang menunjukkan masalah:

async.auto({
  // This needs to run first, but it will finish second
  event: [(next) => {
    emitter.once('awesome', next);
  }],

  // This needs to finish near the end
  checkResults: ['event', (results, next) => {
    assert(results.event.status == 200);
    assert(results.event.msg == 'cool');

    // Do other async stuff...
    somethingAsync(next);
  }],

  // This has to start second, but before the first one finishes
  emit: ['event', (results, next) => {
    event.emit('awesome', {msg: 'cool'}, next);
  }],

  checkEmit: ['emit', (results, next) => {
    // some sort of check that can be async
  },
], done);

event harus dimulai terlebih dahulu, tetapi tidak akan selesai sampai emit terjadi. emit perlu menunggu event untuk memulai, tetapi tidak selesai (alias hanya mengatur handler). Jadi ini tidak akan selesai.

Apakah ada cara untuk melakukan ini dengan perpustakaan async saat ini? (dengan cara yang bersih)

Inilah solusi yang saya inginkan, dengan asumsi ini dapat diimplementasikan secara async

async.auto({
  listen: [(next, done) => {
    client.on(done);
    return next();
  },

  ...
}, callback);

Saya bisa menggunakan paralel, menjalankan emitor dan pendengar (yang mungkin ada beberapa dalam pengujian) sebagai serangkaian tugas. Mengambil hasilnya, dan menjalankan pemeriksaan sebagai bagian kedua. Namun, paralel secara teknis tidak diperlukan untuk memulai tugas secara berurutan (meskipun kemungkinan akan terjadi). Juga, kode menjadi kurang datar, terutama dalam pengaturan yang lebih rumit.

question

Komentar yang paling membantu

Saya pikir itu adalah kasus penggunaan otomatis paling gila yang pernah saya lihat :building_construction:

Semua 4 komentar

Hai @Saevon , terima kasih atas pertanyaannya!

Cara cepat dan bersih untuk melakukannya adalah:

async.auto({
    // This needs to finish near the end
  checkResults: [(next) => {
    return next(null, (results, next) => {
      assert(results.event.status == 200);
      assert(results.event.msg == 'cool');

      // Do other async stuff...
      // somethingAsync(next);
    });
  }],

  // This needs to run first, but it will finish second
  event: ['checkResults', (handler, next) => {
    emitter.once('awesome', handler.checkResults);
    return next();
  }],

  // This has to start second, but before the first one finishes
  emit: ['event', (results, next) => {
    // Should this be emitter.emit instead of event.emit?
    event.emit('awesome', {msg: 'cool'}, next);
  }],

  checkEmit: ['emit', (results, next) => {
    // the results of `checkResults` will be in `results.emit`
    // as the handler on 'awesome' was passed the `next`
    // callback from `emit`

    // some sort of check that can be async
    yourChecks(next);
  }]
}, function done(err) {
    // everything finished running, unless `err` !== `null`
});

Pada dasarnya, Anda hanya menukar ketergantungan event dan checkResults , yang sebenarnya mungkin sedikit lebih bersih, karena event bergantung pada handler di checkResults . checkResults sekarang hanya meneruskan handler ke event .

Perintah eksekusi akan menjadi:
checkResults --> event --> emit --> handler (passed to event from checkResults) --> checkEmit --> done .

Beri tahu saya jika ada yang tidak jelas.

ya, itu menyelesaikan masalah. Terima kasih!

Saya pikir itu adalah kasus penggunaan otomatis paling gila yang pernah saya lihat :building_construction:

Sepakat. Biasanya panggilan balik asinkron dan penghasil acara tidak bercampur dengan baik ...

Apakah halaman ini membantu?
0 / 5 - 0 peringkat