如何在componentDidMount中并行运行两个传感器数据上报函数?
解决传感器上报频率失衡的问题
我来帮你搞定这个两个传感器上报速度不一致的问题!目前你的代码里加速度计设置的是30ms触发一次(每秒大概33次),而方向传感器是50ms一次(每秒20次),这本身就会导致加速度计的上报量远超预期。再加上异步请求如果没做控制,网络延迟还可能让情况更糟。下面是具体的解决方案:
第一步:统一传感器触发间隔
要实现每秒各20条数据,首先把两个传感器的触发间隔都调整为50ms(因为1000ms ÷ 20次 = 50ms),从根源上对齐触发频率:
SensorManager.startAccelerometer(50); // 把原30ms改成50ms SensorManager.startOrientation(50);
第二步:添加请求并发控制
就算传感器按50ms触发,异步的fetch请求如果遇到网络慢的情况,可能会出现多个请求同时在途,导致后端接收到的数量超标。我们可以给每个传感器的上报逻辑加个“请求锁”,确保上一次请求完成后再发送下一次数据:
修改后的完整代码:
componentDidMount() { // 定义两个请求锁,分别控制两个传感器的上报流程 let isAccelerometerRequesting = false; let isOrientationRequesting = false; // 加速度计监听与上报 SensorManager.startAccelerometer(50); DeviceEventEmitter.addListener("Accelerometer", (data) => { // 如果当前正在发送请求,直接跳过本次触发 if (isAccelerometerRequesting) return; isAccelerometerRequesting = true; fetch("http://192.168.1.107:5000/api/or", { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ accelerometer: data }) }) .then(response => response.json()) .then(() => console.log("加速度计数据已上报")) .catch(error => console.error("加速度计上报失败:", error)) .finally(() => { // 请求完成后释放锁,允许下一次上报 isAccelerometerRequesting = false; }); }); // 方向传感器监听与上报 SensorManager.startOrientation(50); DeviceEventEmitter.addListener("Orientation", (data) => { if (isOrientationRequesting) return; isOrientationRequesting = true; fetch("http://192.168.1.107:5000/api/or", { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ orientation: data }) }) .then(response => response.json()) .then(() => console.log("方向传感器数据已上报")) .catch(error => console.error("方向传感器上报失败:", error)) .finally(() => { isOrientationRequesting = false; }); }); }
进阶优化:用节流函数精确控制频率
如果传感器的实际触发频率因为系统调度有波动,你可以用节流函数强制限制上报频率为每秒20次。比如用Lodash的throttle工具:
先安装Lodash(如果项目里还没装):
npm install lodash
然后修改代码:
import { throttle } from 'lodash'; componentDidMount() { // 节流函数:每50ms最多执行一次,确保每秒20次上报 const reportAccelerometer = throttle((data) => { fetch("http://192.168.1.107:5000/api/or", { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ accelerometer: data }) }) .then(res => res.json()) .then(() => console.log("加速度计数据已上报")) .catch(err => console.error("加速度计上报失败:", err)); }, 50, { leading: true, trailing: false }); const reportOrientation = throttle((data) => { fetch("http://192.168.1.107:5000/api/or", { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ orientation: data }) }) .then(res => res.json()) .then(() => console.log("方向传感器数据已上报")) .catch(err => console.error("方向传感器上报失败:", err)); }, 50, { leading: true, trailing: false }); // 传感器可以设置更小的触发间隔,让节流函数控制最终上报频率 SensorManager.startAccelerometer(20); DeviceEventEmitter.addListener("Accelerometer", reportAccelerometer); SensorManager.startOrientation(20); DeviceEventEmitter.addListener("Orientation", reportOrientation); }
这样不管传感器触发多频繁,节流函数都会严格把每个传感器的上报频率控制在每秒20次,完美达到你要的40条/秒(各20条)的目标。
内容的提问来源于stack exchange,提问作者Muhammad Lebda
相关产品推荐
相关产品推荐

