【问题标题】:socket.io and async eventssocket.io 和异步事件
【发布时间】:2019-08-26 00:18:34
【问题描述】:

我在我的 express 服务器中使用 socket.io 和 mongoose。

我的套接字正在使用以下代码监听事件:

socket.on('do something', async () => {
  try {
    await doA();
    doX();
    await doB();
    doY();
    await doC();
  } catch (error) {
    console.log(error);
  }
});

doAdoBdoC 是使用 mongoose 写入数据库的异步操作,但通常它们可以是任何返回承诺的方法。

我希望“做某事”同步运行。 如果事件队列同时处理更多事件,我的 mongodb 会出现一致性问题。

换句话说,如果服务器接收到两个“做某事”事件,我希望仅在第一个事件完全处理后(await doC 之后)才处理接收到的第二个事件。不幸的是,“做某事”回调是异步的。

如何处理?

【问题讨论】:

    标签: javascript asynchronous mongoose socket.io


    【解决方案1】:

    可以通过将要运行的函数添加到数组中,然后逐个运行它们来实现队列。我在下面创建了一个示例。

    let queue = [];
    let running = false;
    
    const delay = (t, v) => {
       return new Promise((resolve) => { 
           setTimeout(resolve.bind(null, "Returned value from Promise"), t)
       });
    }
    
    const onSocketEvent = async () => {
      console.log("Got event");
      if (!running) {
        console.log("Nothing in queue, fire right away");
        return doStuff();
      }
      // There's something in the queue, so add it to it
      console.log("Queuing item")
      queue.push(doStuff);
    }
    
    const doStuff = async () => {
      running = true;
      const promiseResult = await delay(2000);
      console.log(promiseResult);
      
      if (queue.length > 0) {
        console.log("There's more in the queue, run the next one now")
        queue.shift()();
      } else {
        console.log("Queue empty!")
        running = false;
      } 
    }
    
    onSocketEvent();
    setTimeout(() => onSocketEvent(), 1000);
    setTimeout(() => onSocketEvent(), 1500);
    setTimeout(() => onSocketEvent(), 2000);
    setTimeout(() => onSocketEvent(), 2500);

    【讨论】:

    • 非常优雅的解决方案。
    【解决方案2】:

    我建议在每次等待之间添加一个延迟。这将防止发生死锁并解决您的问题。对于这样的事情,我建议使用Caolan's async 库。

    任务延迟示例:

    setTimeout(function() { your_function(); }, 5000); // 5 seconds
    

    如果你的函数没有参数也没有显式接收者,可以直接调用setTimeout(func, 5000)

    有用jQuery timers plugin

    【讨论】:

    • 我不确定我是否完全理解您的回答。你的意思是我必须删除 async 关键字吗?在这种情况下,我什么都等不及了。
    • 抱歉,我的意思是加了一点延迟。另外,也许使它成为布尔方法?如果第一个事件成功通过,则返回一个 true,然后才处理第二个事件
    猜你喜欢
    • 2019-01-12
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多