我应该如何在另一个异步函数中使用异步将来列表?

时间:2020-06-14 20:57:51

标签: flutter asynchronous dart

我正在尝试使用异步方法从网站获取网址列表。 获得网址列表后,我尝试在另一种异步方法中使用这些网址。

这里是获取网址的地址:

void _getData() async {
    final response =
        await http.get('https://www.whateverurl');
    print(response.statusCode);
    dom.Document document = parser.parse(response.body);
    final elements2 = document.getElementsByClassName('image-card-wrapper');
    setState(() {
      //fetches links as /tiger /catalina etc.
      urlList = elements2.map((element) async {
        url = 'https://www.whateverurl' +
            element.getElementsByTagName('a')[0].attributes['href'];
        print(element.getElementsByTagName('a')[0].attributes['href']);
        return url;
      }).toList();
        await _tryFetch(urlList);
    });
  }

成功。我可以得到清单。我无法解决的是:我试图在另一个异步函数中使用此url列表来获取每个项目的特定技术信息。

 _tryFetch(List urls) async {
    String e = '';
    for (var item in urls) {
      try {
        final response2 = await http.get(item);
        dom.Document document2 = parser.parse(response2.body);
        final elements = document2.getElementsByClassName('sqs-block-content');
        elements.forEach((element) {
          if (element.getElementsByTagName('li').isNotEmpty) {
            List a = element.getElementsByTagName('li');
            print(a.length);
            for (var i = 0; i < a.length; i++) {
              var z = a[i].children[0].text ?? '...';
              e = e + z.toString();
            }
          }
          setState(() {
            tekniskInfo.add(e);
            print(tekniskInfo);
          });
        });
      } on Exception catch (_) {
        print('elele');
      }
    }
  }
@override
  void initState() {
    _getData();
    super.initState();
  }

在我的脚手架中,当尝试在ListView.builder中使用此 teksniskInfo [index] 时; 它引发错误:将来的字符串不是字符串的子项...

我试图添加一个按钮来使用_tryFetch()函数。当我按下按钮时,它起作用。但是问题是,当我第一次导航到页面时,它会抛出我提到的错误。

总结一下;如何在另一个未来功能中使用未来列表?

1 个答案:

答案 0 :(得分:2)

前言

  1. async和await关键字支持异步编程,使您可以编写类似于同步代码的异步代码。

  2. 每个标记为async的函数都将返回Future

因此在另一个异步函数中使用异步函数(返回Future)的方法是await函数的结果

Future<String> foo() => ...;

Future<void> bar() {
  final String = await foo();
}

...
await bar(); //somewhere else    
...

返回您的代码

我在_getData()中看到错误-您无法使setState(fn)的函数参数异步,所以接下来是错误代码

setState(() { 
  await foo(); //Error! - you can't await Future in synchronous function
});

您可以通过在异步结果后调用setState来缓解这种情况

void _getData() async {
  ...
  await _tryFetch();
  ...
  setState((){});
}

目前,您需要等待列表中的每个Future(最后等待)

List<Future<String>> urlList = elements2.map((element) async {...

_tryFetch(List urls) async {
  String e = '';
  for (var item in urls) {
    try {
      final response2 = await http.get(await item); //each is Future<String> you need to wait

但是没有必要将async匿名函数放在map(...)

结果将为List<String> urlList = elements2.map((element) {...,无需等待每个列表项

随时通过评论与我联系