Dart Async 不等待完成

Dart Async Does Not Wait for Completion

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

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

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

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 ...
}

我做错了什么?

onDone 部分未达到您的预期。
请尝试:

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

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

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

正如 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(并且一开始就不想使用异步函数),我建议您使用 firstWherelisten:

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(...) 返回的未来。确保这是正确的。