Home > Mobile >  Is a busy-loop the best way for my async function to not complete until bluetooth scan completes?
Is a busy-loop the best way for my async function to not complete until bluetooth scan completes?

Time:09-29

I have an async function in my Flutter app that scans for bluetooth devices. I would prefer that the async function does not complete, until the bluetooth scan completes.

I have implemented this with a busy-loop that block until the scan is complete, and checks every 500ms if this is the case.

Is this the best way to do this in dart? Is this problematic?

var stream = FlutterBlue.instance.scan(timeout: Duration(seconds: 10)); 
stream.listen((ScanResult result) async {
  if (result.device.name == _expectedName) {
    try {
      await result.device.disconnect();
      await result.device.connect();
      _scannedDevice = result.device;
    } catch (error) {
      print(error);
    }
  }
});

while (_scannedDevice == null && await FlutterBlue.instance.isScanning.first) {
  await Future.delayed(Duration(milliseconds: 500));
}

if (_scannedDevice == null) {
  return DeviceConnectResult.deviceNotFound;
}

CodePudding user response:

When browsing the API documentation for FlutterBlue I came across the startScan method that seems to be a good solution for your problem.

Starts a scan and returns a future that will complete once the scan has finished. To observe the results while the scan is in progress, listen to the scanResults stream

FlutterBlue.instance.scanResults.listen((ScanResult result) async {
  if (result.device.name == _expectedName) {
    try {
      await result.device.disconnect();
      await result.device.connect();
      _scannedDevice = result.device;
    } catch (error) {
      print(error);
    }
  }
});
await FlutterBlue.instance.startScan(timeout: Duration(seconds: 10)); 

CodePudding user response:

What I was looking for was 'await for' loop.

An 'await for' loop will process each event in a stream, and synchronously suspend execution until the stream is complete.

var stream = FlutterBlue.instance.scan(timeout: Duration(seconds:10));
await for (var scanResult in stream) {
  if (scanResult.device.name == _expectedName) {
    try {
      await scanResult.device.disconnect();
      await scanResult.device.connect();
      device = scanResult.device;
      await FlutterBlue.instance.stopScan();
    } catch (error) {
      print(error);
    }
  }
}
  • Related