gpt4 book ai didi

javascript - setTimeout 函数触发回调两次

转载 作者:行者123 更新时间:2023-12-04 09:03:45 25 4
gpt4 key购买 nike

我有一个写入功能,它基本上将数据添加到队列并每 500 毫秒发送一次数据,我使用了几个 setTimeouts 来写入数据,如下所示。并且分析日志我怀疑 setTimeout 已被调用两次,我想知道它甚至可能吗?可能的解决办法是什么?


import BleManager from 'react-native-ble-manager';

const BleManagerModule = NativeModules.BleManager;
const bleManagerEmitter = new NativeEventEmitter(BleManagerModule);

class bleHandler {
constructor() {
this.writeQueue = [];
bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', this.handleUpdateValueForCharacteristic);
}

//this function will be called when ble receives data from peripheral.
handleUpdateValueForCharacteristic(data){
// do something with data
//send ack that data is received.
this.writeData("AB:CD:EF:GH:IJ", " Some Important Message text ");
}

writeData(peripheralID, data) {
console.log("Adding data to Queue " + data);
if (this.writeQueue.length == 0) {
this.writeQueue.push(data);
setTimeout(() => this.sendData(peripheralID, data), 500);
} else
this.writeQueue.push(data);

console.log("New Queue Length = " + this.writeQueue.length);
}

sendData = (peripheralID, data) => {
if (data.length > 0 && peripheralID && this.writeQueue.length > 0) {
var byteBuf = this.formatData(data);
console.log("============" + slicedData + " and length = " + slicedData.length + " at Date = " + new Date().valueOf());
console.log("Writing Message : " + byteBuf );
this.handleWriteWithoutResponse(peripheralID, UUID, CHAR, byteBuf).then(() => {
console.log("success writing data ");

data = data.substring(PACKET_SIZE - 5);
if (data.length > 0) {
setTimeout(() => {
this.writeQueue[0] = data;
this.sendData(peripheralID, data)
}, 500);
} else {
this.writeQueue.shift();
setTimeout(() => {
if (this.writeQueue.length > 0)
this.sendData(peripheralID, this.writeQueue[0]);
}, 500);
}
}).catch((error) => {
console.log("error writing data ", error);
});
}
}
}
const bleModule = new bleHandler();
export default bleModule;
日志
11:13:28 log Adding data to Queue " Some Important Message text "
11:13:28 log New Queue Length = 1
11:13:28 log ============" Some Important Message text " and length = 28 at Date = 1597680808275
11:13:28 log Writing Message : 9876543211223A2243222C202233223A7B2241636B223A223230302212345
11:13:28 log ============" Some Important Message text " and length = 28 at Date = 1597680808276
11:13:28 log Writing Message : 9876543211223A2243222C202233223A7B2241636B223A223230302212345
11:13:28 log success writing data
11:13:28 log success writing data

现在,如果您检查 IOS 中的日志,我已经看到发送数据在 (1597680808276 - 1597680808275) 1 毫秒间隔内被调用两次,并且是从 setTimeout 函数调用的。 js 中的 setTimeout 有问题吗?或者可能是 react-native 问题或 safari 问题?我该如何解决这个问题。几年前,我在 nodejs 中看到了类似的问题。
注意:我使用 react-native-ble-manager 发送/接收数据。

最佳答案

问题的根本原因是函数 sendData称自己。

sendData = (peripheralID, data) => {
if (data.length > 0 && peripheralID && this.writeQueue.length > 0) {
// ...
if (data.length > 0) {
setTimeout(() => {
// ...
this.sendData(peripheralID, data) ---> Recursive call
}, 500);
} else {
// ...
setTimeout(() => {
if (this.writeQueue.length > 0)
this.sendData(peripheralID, this.writeQueue[0]); ---> Recursive call
}, 500);
}
// ...
}
多次调用sendData的问题可以通过去掉递归来解决
这是一个示例,其中两个计时器回调都计划在 500 毫秒后发生,并快速连续到达:

function example(a) {
console.log("example:", a, "at", Date.now());
if (a <= 3) {
setTimeout(() => {
example(a * 2);
}, 500);
}
}
// Schedule the calls
example(2);
example(3);

// Keep the thread busy
const end = Date.now() + 600;
while (Date.now() < end) {
}

注意如何
示例:4 在 1597923771329
示例:6 在 1597923771330

在时间上彼此相邻。

关于javascript - setTimeout 函数触发回调两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63502680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com