Управление ожиданием данных в очереди асинхронных запросов

    В сторе Mobx (React Native) есть переменная, хранящая параметры для запросов. Запросы отправляются последовательно с помощью async/await, чтобы каждый следующий запрос ждал завершения предыдущего.

    Устройство отправляет ответы по другому каналу (на основе событий). Проблема: при слишком быстрой отправке устройство иногда «глотает» запросы и не отвечает. Текущее решение - искусственная задержка в 2 секунды через промис, но это неоптимально, так как ответ может прийти быстрее.

    Требуется: отправлять следующий запрос только после получения данных от устройства, контролируя флаг waitingData (true - ждём, false - можно отправлять).

    Текущий код

    async startQueue(deviceID: string, serviceUUID: string, characteristicUUID: string) {
      for (const item of this.queue) {
        this.waitingData = true;
        let getValue = this.BLEService.createDataArr(item.dataType, item.value);
        await BleManager.write(deviceID, serviceUUID, characteristicUUID, getValue);
        await this.receiveDataTrigger(); // задержка 2 секунды
      }
    }
    
    receiveDataTrigger = () => {
      return new Promise(function(resolve) {
        setTimeout(() => {
          resolve("result");
        }, 2000);
      });
    }

    Решение

    Создайте промис, который будет резолвиться, когда waitingData станет false. Для корректного доступа к this (экземпляр стора) используйте стрелочную функцию или замыкание.

    Реализация с checkWaitData

    Добавьте в стор метод waitForData, который возвращает промис, опрашивающий состояние waitingData с помощью setInterval:

    waitForData = () => {
      return new Promise((resolve) => {
        const check = () => {
          if (!this.waitingData) {
            resolve('data_received');
          } else {
            setTimeout(check, 50); // проверка каждые 50 мс
          }
        };
        check();
      });
    }

    Обновлённый метод startQueue

    async startQueue(deviceID: string, serviceUUID: string, characteristicUUID: string) {
      for (const item of this.queue) {
        this.waitingData = true; // Устанавливаем флаг ожидания
        let getValue = this.BLEService.createDataArr(item.dataType, item.value);
        await BleManager.write(deviceID, serviceUUID, characteristicUUID, getValue);
        await this.waitForData(); // Ждём, пока waitingData не станет false
      }
    }

    В обработчике события приёма данных (где вы получаете ответ от устройства) добавьте:

    this.waitingData = false; // Сбрасываем флаг - промис зарезолвится

    Преимущества

    • Адаптивность: следующий запрос отправляется сразу после получения данных, без лишних задержек.
    • Простота: минимальные изменения в коде.
    • Mobx-совместимость: использование стрелочной функции сохраняет контекст this.