美文网首页
flutter async/await异步的坑

flutter async/await异步的坑

作者: 云上听风 | 来源:发表于2019-07-30 09:58 被阅读0次

    虽然flutter主程序是单线程,不需要锁,但是async/await在使用不当的情况下还是会导致数据不同步甚至出错,
    比如下面这个例子:

      List<int>_t1 = List<int>();
      justWait({@required int numberOfSeconds}) async {
        await Future.delayed(Duration(seconds: numberOfSeconds));
      }
    
      test2() async {
        await justWait(numberOfSeconds: 3);
        _t1.clear();
      }
    
      test1() async {
        for (var k in _t1) {
          print("t1: $k");
          await justWait(numberOfSeconds: 1);
        }
        _t1.clear();
      }
    
      test() {
        print('=============================>');
        for (var i = 0; i < 10; i++ ) {
          _t1.add(i);
        }
        test1();
        test2();
        Future.delayed(Duration(seconds: 15), ()=> print(_t1));
      }
    

    输出结果:

    flutter: t1: 1
    flutter: t1: 2
    [VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: Concurrent modification during iteration: Instance(length:0) of '_GrowableList'.
    #0      ListIterator.moveNext (dart:_internal/iterable.dart:337:7)
    #1      Setting.test1 (package:xxx.dart:38:19)
    <asynchronous suspension>
    #2      Setting.test (package:xxx:62:5)
    <asynchronous suspension>
    ... (一堆错误信息)
    flutter: []
    
    

    justWait用来模拟一些长时间操作,当然实际中此处代码可能运行只有几十上百毫秒,这里故意把等待时间设为秒级是为了让问题更容易显现。
    这里的问题是:在test1()方法中循环遍历_t1列表,但是循环中使用了await,此时如果在test2()中同样对_t1列表做了增加或者删除操作,会导致test1循环迭代出错,因为虽然是单线程,但是await会暂时挂起,等待操作完成后才继续,而此时test2中已经把列表清空了,所以会出现上面的问题。

    这儿只是异步可能出错的一个简单例子,其实多个异步对资源的同时访问可能还会有很多情况,所以在使用异步时需要考虑清楚可能出现\color{red}{资源竞争以及时序错乱}的情况。

    相关文章

      网友评论

          本文标题:flutter async/await异步的坑

          本文链接:https://www.haomeiwen.com/subject/ooqgrctx.html