Async: Como enfileirar funções assíncronas es6

Criado em 12 mai. 2017  ·  4Comentários  ·  Fonte: caolan/async

Portanto, tenho algumas funções assíncronas / aguardar e gostaria de colocá-las em fila. Eles são disparados "aleatoriamente" em eventos de websocket específicos, mas precisam ser executados um após o outro. Então, estou testando isso com este código.

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

Eu esperaria que, por exemplo, login() só seja executado após launch() terminado.
Estou fazendo algo errado ou esta biblioteca não é a certa para mim?

question queue

Comentários muito úteis

@codeofsumit desculpe, percebi que meu comentário anterior foi um pouco equivocado, confundi queue com uma função diferente. Espero que eu possa esclarecer.

  1. Como a fila começa? Não pareceu começar após o primeiro empurrão

queue deve começar quando receber um task , ou seja, quando você chamar q.push . Você poderia fornecer um exemplo de código? O código acima foi executado para mim.

Nota lateral: Se você estiver usando funções es7 async com async e transpilar seu código, você terá que envolvê-las em async.asyncify . Veja este comentário para mais informações.

  1. Como posso passar parâmetros para as funções?

Foi aqui que fiquei confuso. O worker você passa para async.queue ao criá-lo, é responsável pelo processamento da tarefa. Se você precisa executar launch , login e goToMonth para cada evento do websocket, você pode simplesmente colocar a função worker . Por exemplo,

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

Caso contrário, se você precisar enfileirar funções, é um pouco complicado, mas você poderia algo como:

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

Esperançosamente, isso está um pouco mais claro.

Todos 4 comentários

Olá @codeofsumit , obrigado pela pergunta!

Olhando para o seu código, acho que o problema está nas últimas três linhas. Você está invocando as funções e enviando seus valores de retorno para queue , ao invés de enviar as funções para queue . Consulte os documentos QueueObject para obter mais informações sobre q.push . Tente alterá-los para:

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

Como você tem concurrency de 1 , a fila só processará login após launch terminar.

@hargasinski Eu pensei assim e tentei, mas isso traz duas novas questões:

  1. Como a fila começa? Não pareceu começar após o primeiro empurrão
  2. Como posso passar parâmetros para as funções?

@codeofsumit desculpe, percebi que meu comentário anterior foi um pouco equivocado, confundi queue com uma função diferente. Espero que eu possa esclarecer.

  1. Como a fila começa? Não pareceu começar após o primeiro empurrão

queue deve começar quando receber um task , ou seja, quando você chamar q.push . Você poderia fornecer um exemplo de código? O código acima foi executado para mim.

Nota lateral: Se você estiver usando funções es7 async com async e transpilar seu código, você terá que envolvê-las em async.asyncify . Veja este comentário para mais informações.

  1. Como posso passar parâmetros para as funções?

Foi aqui que fiquei confuso. O worker você passa para async.queue ao criá-lo, é responsável pelo processamento da tarefa. Se você precisa executar launch , login e goToMonth para cada evento do websocket, você pode simplesmente colocar a função worker . Por exemplo,

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

Caso contrário, se você precisar enfileirar funções, é um pouco complicado, mas você poderia algo como:

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

Esperançosamente, isso está um pouco mais claro.

uhh isso parece muito promissor. Obrigado por nos explicar com tantos detalhes. Ajuda muito!

Além disso: percebi que você está resolvendo problemas neste repositório MUITO rápido (não há muitos problemas em aberto para uma biblioteca tão popular). 👍 muito impressionante - continue com o bom trabalho!

Esta página foi útil?
0 / 5 - 0 avaliações