我在快递服务器中使用socket.io和猫鼬。
我的套接字正在使用以下代码监听事件:
from datetimerange import DateTimeRange
def simplify_ranges(dtrs):
if not dtrs:
return []
dtrs = sorted(dtrs, key=lambda dtr: dtr.start_datetime)
simplified = []
current = dtrs[0]
for dtr in dtrs[1:]:
if current.intersection(dtr).is_valid_timerange():
current = current.encompass(dtr)
else:
simplified.append(current)
current = dtr
simplified.append(current)
return simplified
dtrs = [
DateTimeRange("2019-01-25T00:00:00+0000", "2019-01-30T00:00:00+0000"),
DateTimeRange("2019-01-01T00:00:00+0000", "2019-01-10T00:00:00+0000"),
DateTimeRange("2019-01-21T00:00:00+0000", "2019-01-22T00:00:00+0000"),
DateTimeRange("2019-01-20T00:00:00+0000", "2019-01-21T00:00:00+0000"),
DateTimeRange("2019-01-06T00:00:00+0000", "2019-01-15T00:00:00+0000"),
]
print(*simplify_ranges(dtrs), sep='\n')
# 2019-01-01T00:00:00+0000 - 2019-01-15T00:00:00+0000
# 2019-01-20T00:00:00+0000 - 2019-01-22T00:00:00+0000
# 2019-01-25T00:00:00+0000 - 2019-01-30T00:00:00+0000
socket.on('do something', async () => {
try {
await doA();
doX();
await doB();
doY();
await doC();
} catch (error) {
console.log(error);
}
});
,doA
和doB
是使用猫鼬在数据库上写的异步操作,但通常它们可以是任何返回诺言的方法。
我希望“执行某些操作”同步运行。 如果事件队列同时处理更多事件,则mongodb中存在一致性问题。
换句话说,如果服务器收到两个“执行某事”事件,则我希望仅在第一个事件已完全处理时(在doC
之后)处理接收到的第二个事件。不幸的是,“做某事”回调是异步的。
如何处理?
答案 0 :(得分: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);
答案 1 :(得分:0)
我建议在每次等待之间添加一个延迟。这将防止死锁的发生并解决您的问题。对于这种情况,我建议使用Caolan's异步库。
任务延迟示例:
setTimeout(function() { your_function(); }, 5000); // 5 seconds
如果您的函数没有参数且没有显式接收器,则可以直接调用setTimeout(func, 5000)