Как обработать сокет.события ввода-вывода в их входящем порядке

#javascript #node.js #socket.io

#язык JavaScript #node.js #socket.io

Вопрос:

У меня есть следующая настройка:

 async MyFunction(param) {  //... Do some computation  await WriteToDB() }  io.on('connection', (socket) =gt; {  socket.on('AnEvent', (param) =gt; MyFunction(param)) })  

Когда приходит событие, оно вызывает асинхронную функцию, которая выполняет некоторые вычисления и в конце записывает результат в базу данных с помощью другого асинхронного вызова.

Если у myFunction нет асинхронного вызова для записи базы данных в конце, например

 MyFunction(param) {  //... Do some computation }  

тогда очевидно, что все события будут обработаны в их входящем порядке. Обработка следующего события начнется только после завершения обработки предыдущего. Однако из-за асинхронного вызова базы данных я не знаю, будут ли эти входящие события по-прежнему полностью обработаны в порядке. Я боюсь, что обработка следующего события начнется до завершения предыдущего await WriteToDB() . Как мне изменить код, чтобы полностью обработать их по порядку?

Ответ №1:

Вы правы, что нет никакой гарантии, что входящие события будут обработаны в заказе.

Чтобы достичь того, о чем вы просите, вам понадобится «Очередь сообщений», которая будет периодически проверять наличие новых сообщений и обрабатывать их одно за другим.

 const messageQueue = [];  // SocketIO adding Message to MessageQueue const eventHandler = (message) =gt; {  messageQueue.push(message); }  const messageHandler = () =gt; {  if (messageQueue.length === 0) {  return;  }   const message = messageQueue.shift();   // Handle Message   // If successful, ask for next message  return messageHandler(); }  

Конечно, мой пример довольно наивен, но я надеюсь, что он даст вам общее представление о том, как выполняется то, о чем вы просите.

Если вам нужна более надежная очередь сообщений, загляните в RabbitMQ, BullMQ, Кафка

Комментарии:

1. Как мне вызвать MessageHandler? Похоже, что его нужно вызывать несколько раз. Он вернется после завершения приема всех сообщений, поэтому его нужно вызывать при поступлении новых сообщений.

2. Вашему обработчику сообщений ввода-вывода сокета (обработчику, получившему сообщение от ввода-вывода сокета) необходимо только поместить сообщение в очередь сообщений, затем другой компонент вашего приложения (обычно предоставляемый очередью сообщений) периодически проверяет наличие новых сообщений в очереди (массив MessageQueue в примере), и если есть новое сообщение, оно обработает его.

3. Я настоятельно рекомендую вам изучить, как работают BullMQ, RabbitMQ, Кафка, ваш ответ и все будущие вопросы, скорее всего, будут отражены в их документации.