繁体   English   中英

setTimeout function 触发两次回调

[英]setTimeout function triggers callback twice

我有一个写入 function,它基本上将数据添加到队列并每 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 ms 间隔内被调用两次,它是从 setTimeout function 调用的。js 中的 setTimeout 有问题吗? 或者可能是 react-native 问题或 safari 问题? 我该如何解决这个问题。 几年前,我在 nodejs 中看到过类似的问题。

注意:我使用 react-native-ble-manager 发送/接收数据。

问题的根本原因是 function 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) { }

注意如何

example: 4 at 1597923771329
example: 6 at 1597923771330

在时间上彼此相邻。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM