如何在每次滑块更改时通过蓝牙le发送滑块值,而不发送垃圾邮件“事务已在进行”错误?

1sbrub3j  于 2021-09-13  发布在  Java
关注(0)|答案(2)|浏览(340)

我在一个网站上用gui通过ble控制马达的速度。每次滑块改变位置时,都会触发一个新的“oninput”事件。当您使用滑块时,这种情况约为50倍/秒。由于一次只能发送一个ble传输,且一个ble传输需要约50毫秒,因此存在大量“事务已在进行中”错误。这导致最后几个输入丢失。当你快速地从左到右轻击滑块时,步进电机会接收到位置在中间的某个位置。我想要一个解决方案,其中:
我可以改变滑块,看到步进电机的速度上升和下降,然后我释放滑块。
我还希望在停止滑动之前的最终值是步进电机最终确定的值。
下面是我的黑客解决方案:在输入时调用一个异步方法,尝试发送值。如果失败,那么它会检查是否失败,因为已经有另一个传输正在进行,而不是其他错误。如果是这种情况,它会检查它试图发送的值是否仍然是发送失败后的最新值。只有满足这两个条件,它才会调用自己并重试。
代码如下:

document.getElementById("sldSpeed").oninput = updateSpeed;
let speed = 0;
function updateSpeed() {
    speed = document.getElementById("sldSpeed").value;
    speed = parseInt(speed * 100);
    document.getElementById("lblSpeed").innerHTML = `${speed / 100} cm/s`;
    schrijfRealTimeSpeed(speed);
};

async function schrijfRealTimeSpeed(waarde) {
    schrijfUint32Value(karDelta, waarde)
        .catch((problem) => {
            if (problem.message === "GATT operation already in progress." & waarde === speed)
                schrijfRealTimeSpeed(waarde);
        });
}

(此schrijfuint32value(kardelta,waarde)调用ble模块脚本中的方法,并将数字转换为字节数组,然后使用javascript ble函数karakteristiek.writevaluewithresponse(bytearr))
问:我正在滥用错误系统,这可能不有效。git上的作者说,正确的方法是只在前一个请求返回承诺后发送一个新的请求,这样您就不会首先出现“gaat传输进行中”错误。知道了这一点,有没有更干净、更有效、更好、更像javascript的方法来解决这个问题?

hjzp0vay

hjzp0vay1#

这对你有用吗

document.getElementById("sldSpeed").oninput = updateSpeed;
let speed = 0;
let firstrun = true;
let lastvalue = 0;
function updateSpeed() {
speed = document.getElementById("sldSpeed").value;
speed = parseInt(speed * 100);
document.getElementById("lblSpeed").innerHTML = `${speed / 100}cm/s`;
  if (firstrun == true)
  {
    firstrun = false;
    schrijfRealTimeSpeed(speed);
  }

}
async function schrijfRealTimeSpeed(waarde) {

   const realtimepromise = new Promise(async (resolve, reject) => {
   if (lastvalue!= waarde)
{
 lastvalue = waarde;
await schrijfUint32Value(karDelta, waarde);
resolve();
  } else
  {
  reject();
  firstrun = true;
    }
      });

   realtimepromise.then( (val) => schrijfRealTimeSpeed(speed));

   }
lvmkulzt

lvmkulzt2#

使用IgnumesSolution,我能够编写一个适用于我的应用程序的版本。我删除了一些承诺,并添加了网络错误检查,以防止无限循环:

let speed = 0;
let busy = false;
let speedLastTransmitted = 0;

document.getElementById("sldSpeed").oninput = updateSpeed;

function updateSpeed() {
    speed = document.getElementById("sldSpeed").value;
    speed = parseInt(speed * 100);
    document.getElementById("lblSpeed").innerHTML = `${speed / 100}cm/s`;
    if (busy === false) {
        busy = true;
        schrijfRealTimeSpeed(speed);
    }
}
async function schrijfRealTimeSpeed(waarde) {
    if (speedLastTransmitted === waarde)
        busy = false;
    else {
        schrijfUint32Value(karDelta, waarde)
            .then(() => {
                speedLastTransmitted = waarde;
                schrijfRealTimeSpeed(speed);
            })
            .catch((err) => {
                console.log(err)
            });
    }
}

相关问题