【问题标题】:Async setter / getter in JavaScriptJavaScript 中的异步 setter / getter
【发布时间】:2017-12-21 21:41:28
【问题描述】:

我正在使用需要大量异步操作的网络蓝牙。我已经为设备名称等属性实现了 setter 和 getter。 ES6 默认不支持异步 setter 和 getter,所以我按照here 的建议使用了以下解决方法:

get name() {
  return ( async () => {
    try {
      const data = await this._readData(this.nameCharacteristic);
      const decoder = new TextDecoder("utf-8");
      const name = decoder.decode(data);
      return name;
    } 
    catch (error) {
      return error;
    }
  })();
}

还有:

set name(name) {
  return ( async (name) => {
    const byteArray = new Uint8Array(name.length);
    for (let i = 0; i < name.length; i += 1) {
      byteArray[i] = name.charCodeAt(i);
    }
    return await this._writeData(this.nameCharacteristic, byteArray);
  })(name);
}

我可以使用 getter 成功地执行以下操作:

await device.connect();
await device.name;
await device.<some async BLE operation>

但是下面的 setter 会导致 setter 的引用错误“Uncaught ReferenceError: Invalid left-hand side in assignment”:

await device.connect();
await device.name = "newName";
await device.<some async BLE operation>

如果我删除await 关键字,则错误已修复,但脚本将失败,因为它会同时尝试两个 GATT 操作,这是不支持的。

所以看来我只能等待 getter 而不是 setter。我的 getter 实现是否有问题导致这种情况?在执行异步操作时,我是否必须重新使用 device.nameSet() 之类的函数而不是 setter?

为了记录,_writeData()_readData() 看起来像这样:

async _writeData(characteristic, dataArray) {
  if (!this.bleIsBusy) {
    try {
      this.bleIsBusy = true;
      await characteristic.writeValue(dataArray);
      this.bleIsBusy = false;
    }
    catch (error) {
      return error;
    }
    return Promise.resolve();
  }
  else {
    return Promise.reject(new Error("GATT operation already pending"));
  }
}

async _readData(characteristic) {
  if (!this.bleIsBusy) {
    try {
      this.bleIsBusy = true;
      const dataArray = await characteristic.readValue();
      this.bleIsBusy = false;

      return dataArray;
    }
    catch (error) {
      return error;
    }
  }
  else {
    return Promise.reject(new Error("GATT operation already pending"));
  }
}

【问题讨论】:

  • 在我看来,异步 getter 和 setter 作为代码风格似乎是个坏主意。由于BLE读/写是操作,所以应该使用方法。
  • 是的,我明白这一点。在这个项目中,它开始使用带有“-get”/“-set”后缀的方法来获取和设置 BLE 设备的属性,但在此过程中被更改为 getter/setter 模式,因为它被视为更正确的属性模式.我现在倾向于回到方法,因为异步属性并不是一个真正的东西。将 BLE 设备的属性视为 JS 上下文中的属性可能是错误的。

标签: javascript bluetooth-lowenergy web-bluetooth


【解决方案1】:

也许尝试设置从await this._writeData(this.nameCharacteristic, byteArray);返回的值...

set name(name) {
  return ( async (name) => {
    const byteArray = new Uint8Array(name.length);
    for (let i = 0; i < name.length; i += 1) {
      byteArray[i] = name.charCodeAt(i);
    }
    const result = await this._writeData(this.nameCharacteristic, byteArray);
    return result;
  })(name);
}

【讨论】:

  • 感谢您的反馈,格兰特。不幸的是,这种方法会导致相同的错误。似乎 setter 不能与 await 关键字一起使用,而 getter 可以。
  • @jtg 无赖!但有用的是知道
猜你喜欢
  • 2015-05-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
相关资源
最近更新 更多