Dart 关于Completer (async await future)

来源:zhuanlan.zhihu.com 时间:2020-11-14 23:23
  • Completer

    Completer允许你做某个异步事情的时候,调用c.complete(value)方法来传入最后要返回的值。最后通过c.future的返回值来得到结果,(注意:宣告完成的complete和completeError方法只能调用一次,不然会报错)。看下面的例子更容易理解。

     test() async {
        Completer c = new Completer();
        for (var i = 0; i < 1000; i++) {
          if (i == 900 && c.isCompleted == false) {
            c.completeError('error in $i');
          }
          if (i == 800 && c.isCompleted == false) {
            c.complete('complete in $i');
          }
        }
    
        try {
          String res = await c.future;
          print(res); //得到complete传入的返回值 'complete in 800'
        } catch (e) {
          print(e);//捕获completeError返回的错误
        }
      }

    compute

    在一个页面中做耗时比较大的运算时,就算用了async / await异步处理, ui页面的动画还是会卡顿,因为还是在这个UI线程中做运算,异步只是说我可以先运行其他的,等我这边有结果再返回,但是,记住,我们的计算仍旧是在这个UI线程,仍会阻塞UI的刷新,异步只是在同一个线程的并发操作。

    要解决这个卡顿问题,可以把运算移到另一个线程中,在dart中,这里不是称呼线程,是Isolate,直译叫做隔离,是因为隔离不共享数据,每个隔离中的变量都是不同的,不能相互共享。

    Isolate的操作比较复杂,dart中封装了一层简单的实现

    /// package:flutter/foundation.dart
    Future<R> Function<Q, R>(FutureOr<R> Function(Q), Q, {debugLabel: String})compute
    

    使用方法

    import 'package:flutter/foundation.dart';
    
    function callback( val ){
      ...
      return res
    }
    /// `callback` 必须是顶级方法或者是类的静态方法
    var res = await compute( callback , val );

    简单来讲就是运行var res = await compute( callback , val )函数。callback的传入参数是val, return的数据就是callback的res;

    使用场景

  • 方法执行在几毫秒或十几毫秒左右的,应使用Future
  • 如果一个任务需要几百毫秒或之上的,则建议compute(只有一次返回)或Isolate(用于订阅或有多次返回的