Каковы способы хранения данных, поступающих из сокета каждую секунду?

У меня есть подключение к сокету в моем бэкэнде (express.js) и данные, поступающие из этого сокета каждую секунду, я хочу сохранить эти значения в своей базе данных (postgresql). Поскольку данные поступают каждую секунду, я не хочу сохранять их, когда они приходят, потому что это будет много операций записи. Поэтому я храню их в tempValues и сохраняю значения в базе данных каждую 1 минуту. Но я чувствую, что должен быть лучший способ сделать это вместо использования setInterval. Может быть, сторонняя библиотека или что-то еще? Я могу потерять временные данные, если сервер вышел из строя или что-то случилось.

Вот мой текущий блок кода:

let tempValues = [];

setInterval(() => {
  tempValues.map(async (option, i) => {
    await pool.query(
      "INSERT INTO plc_options (name, value, date) VALUES ($1, $2, $3)",
      [option.name, option.value, option.timestamp]
    );
    if (i === tempValues.length - 1) tempValues = [];
  })

}, 60000);


socket.onAny((eventName, ...args) => {
  tempValues.push({ name: eventName, value: args[0], timestamp: new Date() })
});

Ваше решение (также известное как буферизация) является стандартным и прекрасным. За исключением того, что вам, вероятно, нужно поменять местами массив с пустым перед обновлением (чтобы избежать гонок). В качестве бонуса вам не понадобится if в конце. Так что именно вы ищете? Зачем менять?

freakish 17.12.2022 10:24

Я не был уверен, что это правильный способ решения такой проблемы. Теперь убедился, спасибо.

Jantoma21 17.12.2022 18:30
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам не нужна сторонняя библиотека. Ваша идея в целом нормальная. Это известно как буферизация. Хотя я бы его немного улучшил.

let _tempValues = [];

function getTempValues() {
    return _tempValues;
}

function getAndClearTempValues() {
    let oldTempValues = _tempValues;
    _tempValues = [];
    return oldTempValues;
}

setInterval(() => {
  let values = getAndClearTempValues();
  values.map(async (option, i) => {
    await pool.query(
      "INSERT INTO plc_options (name, value, date) VALUES ($1, $2, $3)",
      [option.name, option.value, option.timestamp]
    );
  })

}, 60000);


socket.onAny((eventName, ...args) => {
  let values = getTempValues();   
  values.push({ name: eventName, value: args[0], timestamp: new Date() })
});

Основное изменение заключается в том, что я заменяю старый tempValues пустым массивом перед циклом по массиву. Таким образом, мы избегаем потенциальной ловушки, когда вы асинхронно перебираете массив, в то время как другой код изменяет его. В качестве бонуса вам не нужен оператор if внутри setInterval.

Другие вопросы по теме