socket.io и асинхронные события - PullRequest
3 голосов
/ 04 апреля 2019

Я использую 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).К сожалению, обратный вызов «сделай что-нибудь» является асинхронным.

Как с этим справиться?

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Можно реализовать очередь, добавив функции, которые вы хотите запустить, в массив, а затем запустив их одну за другой. Я создал пример ниже.

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);
0 голосов
/ 04 апреля 2019

Я бы предложил добавить задержку между каждым ожиданием.Это предотвратит возникновение взаимоблокировок и устранит проблему.Для таких вещей я бы предложил использовать асинхронную библиотеку Caolan's .

Пример задержки задачи:

setTimeout(function() { your_function(); }, 5000); // 5 seconds

Если ваша функция не имеет параметров и не имеет явного получателя, вы можете напрямую вызвать setTimeout(func, 5000)

Полезный Плагин jQuery timers

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...