【问题标题】:Chaining Futures Do Not Execute In Order链式期货不按顺序执行
【发布时间】:2018-07-17 21:11:19
【问题描述】:

我目前正在从蓝牙设备读取变量。这显然需要不确定的时间,所以我使用期货(这个方法在我下面的代码中是 readCharacteristic)。

一次不能进行多个读取操作 - 如果在第一个操作仍在进行时启动了第二个读取操作,Flutter 将抛出错误。

我的理解是,使用 .then() 将 future 链接在一起只会允许下一个语句在上一个调用完成时执行。这个想法似乎是正确的,直到我尝试读取第三个值 - 即由于重叠的读取事件而引发错误时。

这是我的代码:

readCharacteristic(scanDurationCharacteristic)
    .then((list) => sensorScanDuration = list[0].toDouble())
    .then((_) {
  readCharacteristic(scanPeriodCharacteristic)
      .then((list) => sensorScanPeriod = list[0].toDouble());
}).then((_) {
  readCharacteristic(aggregateCharacteristic)
      .then((list) => sensorAggregateCount = list[0].toDouble());
}).then((_) {
  readCharacteristic(appEUICharacteristic)
      .then((list) => appEUI = decimalToHexString(list));
}).then((_) {
  readCharacteristic(devEUICharacteristic)
      .then((list) => devEUI = decimalToHexString(list));
}).then((_) {
  readCharacteristic(appKeyCharacteristic)
      .then((list) => appKey = decimalToHexString(list));
});

有什么更好的方法来确保这些读取事件不会重叠?

【问题讨论】:

  • 为什么要连锁?为什么不把它们全部并行呢?
  • 并行读取会引发异常,所以我不能并行执行。

标签: dart flutter dart-async


【解决方案1】:

虽然 R.C Howell 的答案是正确的,但还是更喜欢使用 async/await 关键字。这更具可读性,并且您出错的可能性更小

Future<void> scanBluetooth() async {
  sensorScanDuration = (await readCharacteristic(scanDurationCharacteristic))[0].toDouble();
  sensorScanPeriod = (await readCharacteristic(scanPeriodCharacteristic))[0].toDouble();
  sensorAggregateCount = (await readCharacteristic(aggregateCharacteristic))[0].toDouble();
  appEUI = await readCharacteristic(appEUICharacteristic).then(decimalToHexString);
  devEUI = await readCharacteristic(devEUICharacteristic).then(decimalToHexString);
  appKey = await readCharacteristic(appKeyCharacteristic).then(decimalToHexString);
}

【讨论】:

    【解决方案2】:

    如果你想链接 Futures,你必须在前一个 Future 的 then 方法中 return 前一个 Future。

    文档说要这样链,

    expensiveA()
        .then((aValue) => expensiveB())
        .then((bValue) => expensiveC())
        .then((cValue) => doSomethingWith(cValue));
    

    与,

    expensiveA()
        .then((aValue) {
            return expensiveB();
        }).then((bValue) {
            return expensiveC();
        }).then((cValue) => doSomethingWith(cValue));
    

    由于这适用于您的情况,

    readCharacteristic(scanDurationCharacteristic)
        .then((list) {
            sensorScanDuration = list[0].toDouble();
            return readCharacteristic(scanPeriodCharacteristic);
        }).then((list) {
            sensorScanPeriod = list[0].toDouble());
            return readCharacteristic(aggregateCharacteristic);
        }).then((list) {
            sensorAggregateCount = list[0].toDouble());
            return readCharacteristic(appEUICharacteristic);
        }).then((list) {
            appEUI = decimalToHexString(list));
            return readCharacteristic(devEUICharacteristic);
        }).then((list) {
            devEUI = decimalToHexString(list));
            return readCharacteristic(appKeyCharacteristic);
        }).then((list) => appKey = decimalToHexString(list));
    

    【讨论】:

      猜你喜欢
      • 2019-11-04
      • 2018-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      • 2015-01-08
      相关资源
      最近更新 更多