首页 > 解决方案 > 如何保证 websocket 回调的有序处理结果?

问题描述

我有一个应用程序,它侦听 websocket 端点并处理从它接收到的数据并将其保存到数据库中。

当同时调用两个回调时会出现竞争条件问题(例如:一个任务可能开始处理,然后另一个任务可能开始处理并更新数据库,然后第一个任务可能更新数据库 - 所以最后数据库更新是乱序)。

我想到的解决方案是记录调用回调的确切时间,处理数据,然后将时间附加到传递到数据库的数据中,并在数据库中将此时间与上次更新时间进行比较并采取相应措施。 我想到的一个可能的问题是时间可能被乱序记录(例如:考虑调用第一个回调,然后调用第二个回调并记录时间,然后为第一个记录时间)打回来)。

你将如何以正确的方式做到这一点?解决这个问题或其他方法去解决它?

编辑更具体地说,因为我打算让程序尽可能实时,我想允许及时处理最新的回调(不等待所有其他以前的回调完全处理),但要确保处理的最终结果(如数据库中记录的那样)遵守回调到达的顺序(未损坏)

标签: javascriptmultithreadingasynchronouswebsocket

解决方案


您可以数据处理程序回调返回完成时间的承诺。

每次从套接字获取新数据时,在处理它之前等待该承诺,然后将生成的承诺存储以等待下一个数据。

看起来像这样:

const ready = Promise.resolve();

socket.on(..., data => {
  ready = ready.then(() => processData(data);
});

这对任何其他代码都没有影响。

编辑:要在锁外做昂贵的工作,你可以写

socket.on(..., data => {
  const result = doExpensiveWork(data); // Returns a promise
  ready = Promise.all(result, ready).then(([result]) => insertData(result));
});

推荐阅读