Async: Cómo poner en cola las funciones asíncronas de es6

Creado en 12 may. 2017  ·  4Comentarios  ·  Fuente: caolan/async

Así que tengo un par de funciones asíncronas / en espera y me gustaría ponerlas en cola. Se disparan "aleatoriamente" en eventos websocket específicos, pero tienen que ejecutarse uno tras otro. Entonces estoy probando esto con 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());

Esperaría que, por ejemplo, login() solo se ejecute después de que launch() finalice.
¿Estoy haciendo algo mal o esta biblioteca no es la adecuada para mí?

question queue

Comentario más útil

@codeofsumit lo siento, me di cuenta de que mi comentario anterior era un poco equivocado, confundí queue con una función diferente. Ojalá pueda aclarar.

  1. ¿Cómo empieza la cola? No parecía comenzar después del primer empujón.

queue debería comenzar cuando obtenga un task , es decir, cuando llame a q.push . ¿Podría proporcionar una muestra de código? El código anterior se ejecutó para mí.

Nota al margen: si está utilizando las funciones es7 async con async y transpilando su código, tendrá que envolverlas en async.asyncify . Consulte este comentario para obtener más información.

  1. ¿Cómo puedo pasar parámetros a las funciones?

Aquí es donde me confundí. El worker que pasa a async.queue cuando lo crea, es responsable de procesar la tarea. Si necesita ejecutar launch , login y goToMonth para cada evento desde websocket, puede simplemente poner la función worker . Por ejemplo,

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

De lo contrario, si necesita poner funciones en cola, es un poco complicado, pero podría 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: []});

Con suerte, esto es un poco más claro.

Todos 4 comentarios

Hola @codeofsumit , ¡gracias por la pregunta!

Al mirar su código, creo que el problema está en las últimas tres líneas. Estás invocando las funciones y empujando su valor de retorno en el queue en lugar de empujar las funciones en el queue . Consulte los documentos de QueueObject para obtener más información sobre q.push . Intente cambiarlos a:

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

Dado que tiene un concurrency de 1 , la cola solo procesará login después de que launch terminado.

@hargasinski Pensé que sí y lo intenté, pero eso trae dos nuevas preguntas:

  1. ¿Cómo empieza la cola? No parecía comenzar después del primer empujón.
  2. ¿Cómo puedo pasar parámetros a las funciones?

@codeofsumit lo siento, me di cuenta de que mi comentario anterior era un poco equivocado, confundí queue con una función diferente. Ojalá pueda aclarar.

  1. ¿Cómo empieza la cola? No parecía comenzar después del primer empujón.

queue debería comenzar cuando obtenga un task , es decir, cuando llame a q.push . ¿Podría proporcionar una muestra de código? El código anterior se ejecutó para mí.

Nota al margen: si está utilizando las funciones es7 async con async y transpilando su código, tendrá que envolverlas en async.asyncify . Consulte este comentario para obtener más información.

  1. ¿Cómo puedo pasar parámetros a las funciones?

Aquí es donde me confundí. El worker que pasa a async.queue cuando lo crea, es responsable de procesar la tarea. Si necesita ejecutar launch , login y goToMonth para cada evento desde websocket, puede simplemente poner la función worker . Por ejemplo,

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

De lo contrario, si necesita poner funciones en cola, es un poco complicado, pero podría 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: []});

Con suerte, esto es un poco más claro.

uhh, esto parece muy prometedor. Gracias por tomarse el tiempo de explicarlo con tanto detalle. ¡Ayuda mucho!

Además: noté que está resolviendo problemas en este repositorio MUY rápido (no hay muchos problemas abiertos para una biblioteca tan popular). 👍 muy impresionante - ¡sigan con el buen trabajo!

¿Fue útil esta página
0 / 5 - 0 calificaciones