Управление ожиданием данных в очереди асинхронных запросов
В сторе 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.