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);
);
doA
、doB
和 doC
是使用 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.on 函数?事件被触发和处理。我正在使用 socket.io、NodeJS 服务器和 Redis.io