首页 > 解决方案 > Dart Async 不等待完成

问题描述

我目前正在尝试等待 BLE 连接导致以下两种结果之一:

不是根据需要返回 true 或 false 值,而是立即返回 null,而无需等待函数完成。

我正在使用 dart 的 Future 和 async 功能来等待连接功能的完成。下面是我的代码:

BLE连接方法:

    static Future<bool> connect(BluetoothDevice d) async {
    // Connect to device
    Duration timeout = new Duration(seconds: 5);

    deviceConnection = _flutterBlue.connect(d, timeout: timeout).listen((s) {
      deviceState = s;
      if (s == BluetoothDeviceState.connected) {
        device = d;

        device.discoverServices().then((s) {
          ... Some service discovery stuff ...
        });
      }
    }, onDone: () {
      return deviceState == BluetoothDeviceState.connected;
    });
  }

从哪里调用连接方法:

bool isConnected = await FlutterBLE.connect(device);

if(isConnected) {
    ... Do some stuff ...
} else {
    ... Do some other stuff ...
}

我在这里做错了什么?

标签: dartflutterdart-async

解决方案


正如 Günther Zöchbauer 所指出的那样,错误在于onDone部分。您正在返回一个没有人会看到的值,并且您没有从周围的函数返回任何内容。

您位于异步函数中,因此您可以使用它await for来迭代流。您还希望在第一次收到连接事件时停止收听流,因为您只关心第一次连接。连接事件流本身永远不会停止。

static Future<bool> connect(BluetoothDevice d) async {
  // Connect to device
  Duration timeout = const Duration(seconds: 5);

  await for (var s in _flutterBlue.connect(d, timeout: timeout)) {
    deviceState = s;
    if (s == BluetoothDeviceState.connected) {
      device = d;

      device.discoverServices().then((s) {
        ... Some service discovery stuff ...
      });
      return true;
    }
  }
  // The stream ended somehow, there will be no further events.
  return false;
}

如果您不想使用await for(并且不使用 async 函数开始),我建议您使用firstWhere在以下位置查找第一个连接(如果有)listen

static Future<bool> connect(BluetoothDevice d) {
  // Connect to device
  Duration timeout = const Duration(seconds: 5);

  return _flutterBlue.connect(d, timeout: timeout).firstWhere((s) {
    return s == BluetoothDeviceState.connected;
  }, orElse: () => null).then((s) {
    if (s == null) return false;
    deviceState = s;
    device = d;
    device.discoverServices().then((s) {
      //... Some service discovery stuff ...
    });
    return true;
  });

没有人等待返回的未来也有点可疑device.discoverServices().then(...)。确保这是正确的。


推荐阅读