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
(并且一开始就不想使用异步函数),我建议您使用 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(...)
返回的未来。确保这是正确的。
我目前正在尝试等待 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
(并且一开始就不想使用异步函数),我建议您使用 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(...)
返回的未来。确保这是正确的。