Async: Cara mengantri fungsi async es6

Dibuat pada 12 Mei 2017  ·  4Komentar  ·  Sumber: caolan/async

Jadi saya memiliki beberapa fungsi async/menunggu dan saya ingin mengantrekannya. Mereka dipecat "secara acak" pada acara websocket tertentu tetapi mereka harus menjalankan satu demi satu. Jadi saya menguji ini dengan kode ini.

const aida = {
  async launch() {
    await someFunction();
  },
  async login() {
    await Auth();
    await UserSettings();
  },
  async goToMonth() {
    await JumpToDefaultMonth();
  }
};


const q = async.queue(function(task, callback) {
  console.log('hello ' + task.name);
  callback();
}, 1);

q.drain = function() {
  console.log('all items have been processed');
};

q.push(aida.launch());
q.push(aida.login());
q.push(aida.goToMonth());

Saya berharap bahwa misalnya login() hanya berjalan setelah launch() selesai.
Apakah saya melakukan sesuatu yang salah atau perpustakaan ini bukan perpustakaan yang tepat untuk saya?

question queue

Komentar yang paling membantu

@codeofsumit maaf, saya menyadari komentar saya sebelumnya sedikit salah arah, saya mendapat queue bingung dengan fungsi yang berbeda. Semoga saya bisa mengklarifikasi.

  1. Bagaimana antrian dimulai? Sepertinya tidak dimulai setelah dorongan pertama

queue harus dimulai ketika mendapat task , yaitu ketika Anda memanggil q.push . Bisakah Anda memberikan contoh kode? Kode di atas berjalan untuk saya.

Catatan tambahan: Jika Anda menggunakan fungsi es7 async dengan async dan mengubah kode Anda, Anda harus membungkusnya dalam async.asyncify . Lihat komentar ini untuk info lebih lanjut.

  1. Bagaimana saya bisa meneruskan parameter ke fungsi?

Di sinilah saya menjadi bingung. worker Anda berikan ke async.queue saat Anda membuatnya, bertanggung jawab untuk memproses tugas. Jika Anda perlu menjalankan launch , login , dan goToMonth untuk setiap acara dari websocket, Anda cukup memasukkan fungsi worker . Sebagai contoh,

const q = async.queue(function(task, callback) {
  async.series([
    async function() {
      await aida.launch(task.foo, task.boo);
    },
    async function() {
      await aida.login(task.baz);
    },
    // etc...
  ], callback);
}, 1);

// on a websocket event
q.push({foo: websocketData.foo, bar: websocketData.bar, baz: websocketData.baz});

Jika tidak, jika Anda perlu mengantri fungsi, ini sedikit meretas, tetapi Anda bisa melakukan sesuatu seperti:

const q = async.queue(async function(task) {
  await task.func.apply(null, task.args);
}, 1);

// on a websocket event
q.push({func: aida.launch, args: [websocketData.foo, websocketData.bar]});
q.push({func: aida.login, args: [websocketData.baz]});
q.push({func: aida.goToMonth, args: []});

Semoga ini sedikit lebih jelas.

Semua 4 komentar

Hai @codeofsumit , terima kasih atas pertanyaannya!

Dari melihat kode Anda, saya pikir masalahnya ada pada tiga baris terakhir. Anda menjalankan fungsi, dan mendorong nilai pengembaliannya ke queue sebagai lawan dari mendorong fungsi ke dalam queue . Lihat QueueObject dokumen untuk info lebih lanjut tentang q.push . Coba ubah ke:

q.push(aida.launch);
q.push(aida.login);
q.push(aida.goToMonth);

Karena Anda memiliki concurrency dari 1 , antrian hanya akan memproses login setelah launch selesai.

@hargasinski Saya pikir begitu dan mencobanya tetapi itu membawa dua pertanyaan baru:

  1. Bagaimana antrian dimulai? Sepertinya tidak dimulai setelah dorongan pertama
  2. Bagaimana saya bisa meneruskan parameter ke fungsi?

@codeofsumit maaf, saya menyadari komentar saya sebelumnya sedikit salah arah, saya mendapat queue bingung dengan fungsi yang berbeda. Semoga saya bisa mengklarifikasi.

  1. Bagaimana antrian dimulai? Sepertinya tidak dimulai setelah dorongan pertama

queue harus dimulai ketika mendapat task , yaitu ketika Anda memanggil q.push . Bisakah Anda memberikan contoh kode? Kode di atas berjalan untuk saya.

Catatan tambahan: Jika Anda menggunakan fungsi es7 async dengan async dan mengubah kode Anda, Anda harus membungkusnya dalam async.asyncify . Lihat komentar ini untuk info lebih lanjut.

  1. Bagaimana saya bisa meneruskan parameter ke fungsi?

Di sinilah saya menjadi bingung. worker Anda berikan ke async.queue saat Anda membuatnya, bertanggung jawab untuk memproses tugas. Jika Anda perlu menjalankan launch , login , dan goToMonth untuk setiap acara dari websocket, Anda cukup memasukkan fungsi worker . Sebagai contoh,

const q = async.queue(function(task, callback) {
  async.series([
    async function() {
      await aida.launch(task.foo, task.boo);
    },
    async function() {
      await aida.login(task.baz);
    },
    // etc...
  ], callback);
}, 1);

// on a websocket event
q.push({foo: websocketData.foo, bar: websocketData.bar, baz: websocketData.baz});

Jika tidak, jika Anda perlu mengantri fungsi, ini sedikit meretas, tetapi Anda bisa melakukan sesuatu seperti:

const q = async.queue(async function(task) {
  await task.func.apply(null, task.args);
}, 1);

// on a websocket event
q.push({func: aida.launch, args: [websocketData.foo, websocketData.bar]});
q.push({func: aida.login, args: [websocketData.baz]});
q.push({func: aida.goToMonth, args: []});

Semoga ini sedikit lebih jelas.

uhh ini terlihat sangat menjanjikan. Terima kasih telah meluangkan waktu untuk menjelaskannya dengan begitu detail. Membantu banyak!

Juga: Saya perhatikan Anda menyelesaikan masalah dalam repo ini SANGAT cepat (tidak banyak masalah terbuka untuk perpustakaan yang begitu populer). 👍 sangat mengesankan - teruslah bekerja dengan baik!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat