加载中...

Flutter中的Future和Completer以及compute


Future

FutureFlutter中表示异步操作结果的对象。当我们需要执行一个耗时的操作时,可以将其封装在一个Future对象中,然后继续执行其他任务,而不需要等待该操作完成。一旦操作完成,Future将提供该操作的结果。通常使用asyncawait关键字来处理Future。例如,我们可以创建一个返回Future的异步函数:

Future<int> fetchData() async {
  // 模拟一个耗时的操作
  await Future.delayed(Duration(seconds: 1));
  return 0;
}

然后,我们可以在其他地方调用这个异步函数,并使用await关键字等待其结果:

void main() async {
  int data = await fetchData();
  print('data = $data');
}

当fetchData异步操作完成后,await将得到该操作的结果,并继续执行后续代码。

Completer

CompleterFlutter中用于手动完成Future的对象。有时候我们需要手动控制一个异步任务的完成,并将其结果传递给Future,这时就可以使用Completer。通过Completer,我们可以创建一个未完成Future,并在合适的时机手动完成它。下面是一个示例:

Future<int> fetchData() {
  Completer<int> completer = Completer();
  // 模拟一个耗时的操作
  Future.delayed(Duration(seconds: 1), () {
    completer.complete(0); // 手动完成Future并传递结果
  });
  return completer.future;
}

我们创建了一个Completer对象,然后在异步任务完成时调用completer.complete(result)来完成Future并传递结果。

使用这个Completer的方法和之前的Future使用方式是相同的:

void main() async {
  int data = await fetchData();
  print('data = $data');
}

上述代码中,我们等待异步任务完成,Completer将传递的结果提供给了Future

注意:宣告完成的completecompleteError方法只能调用一次,不然会报错。

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 );

总结

FutureCompletercompute三者都可以用于处理异步任务,但它们在用法上有一些差异。

Future会自动在异步任务完成时提供结果,而Completer允许手动控制Future的完成。使用asyncawait关键字可以使异步代码更加简洁易读,因此在绝大多数情况下,使用Future更为常见。 根据实际需求,如果你需要手动控制异步任务的完成,可以使用Completer,否则通常使用Future即可。

如果一个任务需要几百毫秒或之上的,为了避免UI线程卡顿建议使用compute(只有一次返回)或Isolate(用于订阅或有多次返回的)

如果方法执行在几毫秒或十几毫秒左右的,建议使用使用FutureCompleter


文章作者: km
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 km !
  目录