Async: Как поставить в очередь асинхронные функции es6

Созданный на 12 мая 2017  ·  4Комментарии  ·  Источник: caolan/async

Итак, у меня есть пара функций async / await, и я хотел бы поставить их в очередь. Они запускаются «случайным образом» при определенных событиях веб-сокета, но должны выполняться одно за другим. Итак, я тестирую это с помощью этого кода.

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());

Я ожидал, что, например, login() запускается только после завершения launch() .
Я что-то делаю не так или эта библиотека мне не подходит?

question queue

Самый полезный комментарий

@codeofsumit извините, я понял, что мой предыдущий комментарий был немного неверным, я перепутал queue с другой функцией. Надеюсь, я смогу уточнить.

  1. Как начинается очередь? Похоже, не запустился после первого толчка

queue должен запускаться, когда он получает task , т.е. когда вы вызываете q.push . Не могли бы вы предоставить образец кода? Приведенный выше код работал для меня.

Боковое примечание: если вы используете функции es7 async с async и транслируете свой код, вам придется заключить их в async.asyncify . См. Этот комментарий для получения дополнительной информации.

  1. Как передать параметры функциям?

Вот где я запутался. worker вы передаете async.queue при его создании, отвечает за обработку задачи. Если вам нужно запускать launch , login и goToMonth для каждого события из веб-сокета, вы можете просто вставить функцию worker . Например,

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});

В противном случае, если вам нужно поставить функции в очередь, это немного взломано, но вы можете что-то вроде:

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: []});

Надеюсь, это немного яснее.

Все 4 Комментарий

Привет @codeofsumit , спасибо за вопрос!

Глядя на ваш код, я думаю, что проблема в последних трех строках. Вы вызываете функции и помещаете их возвращаемое значение в queue а не помещаете функции в queue . Посмотреть QueueObject документов для получения дополнительной информации о q.push . Попробуйте изменить их на:

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

Поскольку у вас есть concurrency из 1 , очередь будет обрабатывать login после завершения launch .

@hargasinski Я так думал и пробовал, но

  1. Как начинается очередь? Похоже, не запустился после первого толчка
  2. Как передать параметры функциям?

@codeofsumit извините, я понял, что мой предыдущий комментарий был немного неверным, я перепутал queue с другой функцией. Надеюсь, я смогу уточнить.

  1. Как начинается очередь? Похоже, не запустился после первого толчка

queue должен запускаться, когда он получает task , т.е. когда вы вызываете q.push . Не могли бы вы предоставить образец кода? Приведенный выше код работал для меня.

Боковое примечание: если вы используете функции es7 async с async и транслируете свой код, вам придется заключить их в async.asyncify . См. Этот комментарий для получения дополнительной информации.

  1. Как передать параметры функциям?

Вот где я запутался. worker вы передаете async.queue при его создании, отвечает за обработку задачи. Если вам нужно запускать launch , login и goToMonth для каждого события из веб-сокета, вы можете просто вставить функцию worker . Например,

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});

В противном случае, если вам нужно поставить функции в очередь, это немного взломано, но вы можете что-то вроде:

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: []});

Надеюсь, это немного яснее.

эээ, это выглядит очень многообещающим. Спасибо, что нашли время, чтобы объяснить это так подробно. Очень помогает!

Также: я заметил, что вы ОЧЕНЬ быстро решаете проблемы в этом репо (не так много открытых проблем для такой популярной библиотеки). 👍 очень впечатляет - продолжайте в том же духе!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги