Async: 如何对 es6 异步函数进行排队

创建于 2017-05-12  ·  4评论  ·  资料来源: caolan/async

所以我有几个 async/await 函数,我想对它们进行排队。 它们在特定的 websocket 事件上“随机”触发,但它们必须一个接一个地运行。 所以我用这段代码测试这个。

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和transpiling你的代码,你将不得不将它们包装在async.asyncify 。 有关更多信息,请参阅此评论

  1. 如何将参数传递给函数?

这是我感到困惑的地方。 创建它时传递给async.queueworker负责处理任务。 如果您需要为来自 websocket 的每个事件运行launchlogingoToMonth ,您只需放入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);

由于您有concurrency1 ,队列只会在launch完成后处理login

@hargasinski我这么认为并尝试过,但这带来了两个新问题:

  1. 队列是如何开始的? 第一次推送后好像没有启动
  2. 如何将参数传递给函数?

@codeofsumit抱歉,我意识到我之前的评论有点误导,我将queue与不同的功能混淆了。 希望我能澄清一下。

  1. 队列是如何开始的? 第一次推送后好像没有启动

queue应该在它获得task ,即当您调用q.push 。 你能提供一个代码示例吗? 上面的代码为我运行。

附注:如果您使用的是ES7 async与功能async和transpiling你的代码,你将不得不将它们包装在async.asyncify 。 有关更多信息,请参阅此评论

  1. 如何将参数传递给函数?

这是我感到困惑的地方。 创建它时传递给async.queueworker负责处理任务。 如果您需要为来自 websocket 的每个事件运行launchlogingoToMonth ,您只需放入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: []});

希望这更清楚一点。

嗯,这看起来很有希望。 感谢您花时间如此详细地解释它。 有很大帮助!

另外:我注意到你正在非常快地解决这个 repo 中的问题(对于这样一个流行的库来说,没有多少未解决的问题)。 👍 非常令人印象深刻 - 继续努力!

此页面是否有帮助?
0 / 5 - 0 等级