如何使未来函数等待流完成?

huangapple go评论63阅读模式
英文:

How can i make future function to wait for a stream to complete?

问题

Future notifyRead(Guid characteristic, BuildContext context) async {
    try {
      if (await FlutterBlue.instance.isOn) {
        BluetoothCharacteristic charToTarget = _characteristics
            .firstWhere((element) => element.uuid == characteristic);
        await charToTarget.setNotifyValue(true);
        clearInfo();
        var stream = charToTarget.value.listen(
          (value) {
            var temp = String.fromCharCodes(value);
            _info.add(temp);
            print(temp);
            notifyListeners();
            if (temp.startsWith("batt")) {
              updateBattValues(temp);
            }
            updateWifiVerificationStatus();

            if (_info.length == 17) {
              log("Finished Sending Data ");
              _notifyFinished = true;
              notifyListeners();
              return;
            }
          },
        );
        await charToTarget.write(INFO.codeUnits);
        
        // Add this part to wait for the stream to complete
        await stream.drain();
      } else {
        Fluttertoast.showToast(msg: "Seems like your Bluetooth is turned off");
      }
    } catch (e) {
      log("Some error occurred in retrieving info ${e.toString()}");
      Fluttertoast.showToast(
          msg: "Some error occurred in retrieving info ${e.toString()}");
    }
  }

以上是您提供的代码的翻译,我已经将其修改,以等待流完成。在流的末尾使用await stream.drain();来等待流完成,然后才会继续执行后续代码。这会确保notifyRead方法等待流的完成。

英文:
Future notifyRead(Guid characteristic, BuildContext context) async {
    try {
      if (await FlutterBlue.instance.isOn) {
        BluetoothCharacteristic charToTarget = _characteristics
            .firstWhere((element) => element.uuid == characteristic);
        await charToTarget.setNotifyValue(true);
        clearInfo();
        var stream = charToTarget.value.listen(
          (value) {
            var temp = String.fromCharCodes(value);
            _info.add(temp);
            print(temp);
            notifyListeners();
            if (temp.startsWith("batt")) {
              updateBattValues(temp);
            }
            updateWifiVerificationStatus();

            if (_info.length == 17) {
              log("Finished Sending Data ");
              _notifyFinished = true;
              notifyListeners();
              return;
            }
          },
        );
        await charToTarget.write(INFO.codeUnits);
      } else {
        Fluttertoast.showToast(msg: "Seems like your Bluetooth is turned off");
      }
    } catch (e) {
      log("Some error occurred in retrieving info ${e.toString()}");
      Fluttertoast.showToast(
          msg: "Some error occurred in retrieving info ${e.toString()}");
    }
  }

I want this notifyRead method to wait for the stream inside to complete.But I am not able to achieve the same.The stream does not have an end associated with it , all I know is the stream outputs 17 values(that I save in _info array ) , so the check the length of the data and mark the end.
This notifyRead method is called by a button's onTap.I want to show a till the stream finishes.

答案1

得分: 1

这在使用 await for 时非常简单:

void main() async {
  print('before');
  await asyncFunction();
  print('after');
}

Future<void> asyncFunction() async {
  int count = 0;
  await for (var _ in streamFunction()) {
    count++;
    print('count = $count');
    if (count == 17) {
      break;
    }
  }
}

Stream<int> streamFunction() async* {
  for (var i = 0; ; i++) {
    yield i;
  }
}

输出:

before
count = 1
count = 2
count = 3
count = 4
count = 5
count = 6
count = 7
count = 8
count = 9
count = 10
count = 11
count = 12
count = 13
count = 14
count = 15
count = 16
count = 17
after
英文:

This is very straightforward when using await for:

void main() async {
  print(&#39;before&#39;);
  await asyncFunction();
  print(&#39;after&#39;);
}

Future&lt;void&gt; asyncFunction() async {
  int count = 0;
  await for (var _ in streamFunction()) {
    count++;
    print(&#39;count = $count&#39;);
    if (count == 17) {
      break;
    }
  }
}

Stream&lt;int&gt; streamFunction() async* {
  for (var i = 0; ; i++) {
    yield i;
  }
}

Output:

before
count = 1
count = 2
count = 3
count = 4
count = 5
count = 6
count = 7
count = 8
count = 9
count = 10
count = 11
count = 12
count = 13
count = 14
count = 15
count = 16
count = 17
after

huangapple
  • 本文由 发表于 2023年3月8日 15:34:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75670361.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定