Asynchronous Dart-从流订阅块返回数据

Asynchronous Dart-从流订阅块返回数据,asynchronous,dart,async-await,stream,Asynchronous,Dart,Async Await,Stream,我用listen方法订阅一个流,这样我就可以在数据进入时处理它。如果我找到了我要查找的内容,我想取消流并从流订阅块返回数据 我有一个正常工作的实现,但是我使用了一个补足符来阻止函数立即返回,它感觉很混乱,所以我想知道是否有更好的方法来实现这一点。以下是我的代码片段: Future<String> _extractInfo(String url) async { var data = <int>[]; var client = http.Client();

我用listen方法订阅一个流,这样我就可以在数据进入时处理它。如果我找到了我要查找的内容,我想取消流并从流订阅块返回数据

我有一个正常工作的实现,但是我使用了一个补足符来阻止函数立即返回,它感觉很混乱,所以我想知道是否有更好的方法来实现这一点。以下是我的代码片段:

Future<String> _extractInfo(String url) async {
    var data = <int>[];
    var client = http.Client();
    var request = http.Request('GET', Uri.parse(url));
    var response = await client.send(request);

    var process = Completer();
    var interestingData = '';

    StreamSubscription watch;

    watch = response.stream.listen((value) async {
      data.clear(); //clear the previous stale data from the list so searching can be faster
      data.addAll(value);

      if (
        hasInterestingData(data) //search the bytelist for the data I'm looking for
      ){
        interestingData = extractInterestingData(data) //extract the data if it's been found. This is what I want my function to return;
        await watch.cancel(); //cancel the stream subscription if the data has been found. ie: Cancel the download
        process.complete('done'); //complete the future, so the function can return interestingData.
      }
    });

    watch.onDone(() {
      //complete the future if the data was not found...so the function will return an empty string
      if (!process.isCompleted) {
        process.complete('done');
      }
    });

    await process.future; //blocks the sync ops below so the function doesn't return immediately
    client.close();
    return interestingData;
  }
Future\u extractInfo(字符串url)异步{
var数据=[];
var client=http.client();
var request=http.request('GET',Uri.parse(url));
var response=wait client.send(请求);
var进程=Completer();
var利息数据=“”;
流动订阅观察;
watch=response.stream.listen((值)异步{
data.clear();//从列表中清除以前的陈旧数据,以便更快地进行搜索
data.addAll(值);
如果(
hasInterestingData(data)//在bytelist中搜索我要查找的数据
){
interestingData=extractInterestingData(data)//如果找到数据,则提取数据。这是我希望函数返回的结果;
wait watch.cancel();//如果找到数据,则取消流订阅。即:取消下载
process.complete('done');//完成未来,这样函数就可以返回感兴趣的数据。
}
});
看,一块(){
//如果找不到数据,请填写future…这样函数将返回空字符串
如果(!process.isCompleted){
过程。完成(“完成”);
}
});
wait process.future;//阻止下面的同步操作,因此函数不会立即返回
client.close();
返回利息数据;
}

当您使用
异步
函数时,您应该使用
等待
处理类似的事情

Future\u extractInfo(字符串url)异步{
var client=http.client();
var request=http.request('GET',Uri.parse(url));
var response=wait client.send(请求);
等待(response.stream中的var数据){
如果(有利息数据(数据)){
return extractinginterestingdata(data);//退出循环将取消订阅。
}
}
返回“完成”;
}
然而,虽然这种方法相当于您的代码,但它可能也有同样的缺陷。
除非您寻找的是单个字节,否则您将面临在连续数据事件之间分割所需内容的风险。您确实需要保留前一个数据数组的某些部分,或总结您已经看到的内容的某些状态,但保留的程度取决于您实际查找的内容。

谢谢,我通过在找到数据后保存上一个数据块的一部分和下一个数据块的一部分来解决此缺陷。