socket.io 和异步事件

Posted

技术标签:

【中文标题】socket.io 和异步事件【英文标题】:socket.io and async events 【发布时间】: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 之后)才处理接收到的第二个事件。不幸的是,“做某事”回调是异步的。

如何处理?

【问题讨论】:

【参考方案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,然后才处理第二个事件

以上是关于socket.io 和异步事件的主要内容,如果未能解决你的问题,请参考以下文章

socket.io |异步响应是不是按顺序堆叠?

自定义异步IO模块开发

如何检测未注册的socket.io事件?

如何在前端获取 socket.on 函数?事件被触发和处理。我正在使用 socket.io、NodeJS 服务器和 Redis.io

Py修行路 socket + select 实现 异步IO模块

Socket.io-防止触发多个事件