Flutter Completer 的妙用

适用场景:
1.例如在app启动的时候,需要初始化数据(例如从服务端拉取数据),初始化的时间比较久,或者受限于网络,时间不可控,
后面用户点击了某个操作,这个操作依赖于初始化,就需要等待初始化完成,就可用使用Completer类来实现在这种效果。
2.将异步监听的方式,改成await的方式,更符合dart的使用方式。

Completer的方法就以下几个:
  completer.future;
  completer.isCompleted;
  completer.complete();
  completer.completeError(error);

  针对场景1:

一般用法:

import 'dart:async';

void main() {
  init();
  // 例如用户点击触发的时候,执行doSomething方法,
  // doSomething方法内部需要等待init方法执行完成才可用继续完成用户的操作。
  doSomething();
}

Completer<void> completer = Completer<void>();

Future<void> init() async {
  print("正在执行初始化的操作");
  await Future.delayed(const Duration(seconds: 2));
  completer.complete();
  print("初始化完成");
}

Future<void> doSomething() async {
  print("执行其他操作");
  await completer.future;
  print("执行其他操作完成");
}

  执行结果:

正在执行初始化的操作
执行其他操作
// 等待2秒后
初始化完成
执行其他操作完成

  也可抛出异常:

import 'dart:async';

void main() {
  init();
  // 例如用户点击触发的时候,执行doSomething方法,
  // doSomething方法内部需要等待init方法执行完成才可用继续完成用户的操作。
  doSomething();
}

Completer<void> completer = Completer<void>();

Future<void> init() async {
  print("正在执行初始化的操作");
  await Future.delayed(const Duration(seconds: 2));
  // completer.complete();
  completer.completeError("初始化失败");
  print("初始化完成");
}

Future<void> doSomething() async {
  print("执行其他操作");
  try {
    await completer.future;
  } catch (e) {
    print(e);
  }
  print("执行其他操作完成");
}

  执行结果:

正在执行初始化的操作
执行其他操作
// 等待2秒 初始化完成 初始化失败 执行其他操作完成

  针对适用场景2的demo:

import 'dart:async';

void main() {
  doSomething();
}

typedef OnSuccess<T> = void Function(T response);

typedef OnFailed = void Function(int errCode, String errMsg);

Future<void> doSomething() async {
  Completer<String> completer = Completer<String>();
  // 例如网络请求异步,或者是其他使用监听器来实现异步的,都可用改成async的方式
  requestSomething(
    (response) => {completer.complete(response)},
    (errCode, errMsg) => {
      completer.completeError({"errCode": errCode, "errMsg": errMsg})
    },
  );
  try {
    String response = await completer.future;
    // 成功
    print("执行响应:$response");
  } catch (e) {
    print(e);
  }
}

void requestSomething(OnSuccess<String> onSuccess, OnFailed onFailed) {
  // Future.delayed(const Duration(seconds: 2))
  //     .then((value) => {onSuccess("执行成功")});
  Future.delayed(const Duration(seconds: 2))
      .then((value) => {onFailed(90001, "执行失败")});
}

 

posted @ 2023-02-03 10:39  柏。  阅读(1822)  评论(0编辑  收藏  举报