Flutter学习(九)Dart异步

2020-04-22  本文已影响0人  yanhooIT

Dart是如何完成耗时操作的?

概念补充

Dart是如何搞定异步的?

Future
import 'dart:io';

main(List<String> args) {
  print("main start");

  // 模拟一个网络请求
  var future = getNetworkData();

  // 通过.then(成功回调函数)的方式来监听Future内部执行完成时获取到的结果
  future.then((String value) {
    print(value);
  })
  // 通过.catchError(失败或异常回调函数)的方式来监听Future内部执行失败或者出现异常时的错误信息
  .catchError((err) {
    print(err);
  })
  // 这里是一定会执行的
  .whenComplete(() {
    print("代码执行完毕");
  });

  print("main end");
}

Future<String> getNetworkData() {
  return Future<String>(() {// 将耗时的操作包裹到Future的回调函数中
    // 模拟网络请求
    sleep(Duration(seconds: 3));

    // 模拟有返回结果, 那么就执行Future对应的then的回调
    return "result";

    // 模拟有错误信息, 需要在Future回调中抛出一个异常
    // throw Exception("我是错误信息");
  });
}
import 'dart:io';

main(List<String> args) {
  print("main start");

  // Future的链式调用
  Future(() {
    // 1.发送第一次请求
    sleep(Duration(seconds: 3));
    return "第一次的结果";
  }).then((res) {
    print(res);

    // 2.发送的第二次请求
    sleep(Duration(seconds: 2));
    return "第二次的结果";
    // throw Exception("第二次异常");
  }).then((res) {
    print(res);

    // 3.发送的第三次请求
    sleep(Duration(seconds: 1));
    return "第三次的结果";
  }).then((res) {
    print(res);
  }).catchError((err) {
    // 捕获异常
    print(err);
  });

  print("main end");
}
main(List<String> args) {
  /** 打印结果
   * futureValueMethod start
   * futureValueMethod end
   * 哈哈哈
   * 
   * 为什么“哈哈哈”是在最后打印的呢???
   *  因为Future中的then会作为新的任务会加入到事件队列中(Event Queue),加入之后你肯定需要排队执行了
   */
  // futureValueMethod();

  /** 打印结果
   * futureErrorMethod start
   * futureErrorMethod end
   * 错误信息
   * 
   * 为什么“错误信息”是在最后打印的呢???
   *  答案如上所述
   */
  // futureErrorMethod();

  /** 打印结果
   * futureDelayedMethod start
   * futureDelayedMethod end
   * result
   */
  futureDelayedMethod();
}

void futureValueMethod() {
  print("futureValueMethod start");
  
  // 直接获取一个完成的Future,该Future会直接调用then的回调函数
  Future.value("哈哈哈").then((res) {
    print(res);
  });
  
  print("futureValueMethod end");
}

void futureErrorMethod() {
  print("futureErrorMethod start");
  
  // 直接获取一个完成的Future,但是一个发生异常的Future,该Future会直接调用catchError的回调函数
  Future.error("错误信息").catchError((err) {
    print(err);
  });
  
  print("futureErrorMethod end");
}

void futureDelayedMethod() {
  print("futureDelayedMethod start");
  
  // 延迟一定时间后执行回调函数,执行完回调函数后会执行then的回调
  Future<String>.delayed(Duration(seconds: 3), () {
    return "result";
  }).then((res) {
    print(res);
  });
  
  print("futureDelayedMethod end");
}
async、await
import 'dart:io';

main(List<String> args) {
  print("main start");

  var result = getNetworkData().then((res) {
    print(res);
  });
  print(result);

  print("main end");
}

/**
 * 解决两个问题:
 *  1.await必须在async函数中才能使用
 *  2.async函数返回的结果必须是一个Future
 *  3.返回值会默认被包装在一个Future中
 */
Future getNetworkData() async {
  await sleep(Duration(seconds: 3));
  return "Hello World";
}
import 'dart:io';

main(List<String> args) {
  print("main start");

  /** 打印结果
  * main start
  * main end
  * argument1
  * argument12
  * argument123
  */
  getData().then((res) {
    print(res);
  }).catchError((err) {
    print(err);
  });

  print("main end");
}

Future getData() async {
  // 调用第1次网络请求
  var res1 = await getNetworkData("argument1");
  print(res1);

  // 调用第2次网络请求
  var res2 = await getNetworkData(res1+"2");
  print(res2);

  // 调用第3次网络请求
  var res3 = await getNetworkData(res2+"3");
  return res3;
}

Future getNetworkData(String arg) {
  return Future(() {
    sleep(Duration(seconds: 3));
    return arg;
  });
}

Isolate

import 'dart:isolate';

main(List<String> args) {
  print("main start");

  // 开启一个新的Isolate
  Isolate.spawn(calc, 100);

  print("main end");
}

void calc(int count) {
  var total = 0;
  for (var i = 0; i < count; i++) {
    total += i;
  }
  print(total);
}
import 'dart:isolate';

main(List<String> args) async {
  print("main start");

  // 1.创建管道
  ReceivePort receivePort = ReceivePort();

  // 2.创建新的Isolate
  Isolate isolate = await Isolate.spawn<SendPort>(foo, receivePort.sendPort);

  // 3.监听管道消息
  receivePort.listen((message) {
    print("message: $message");

    // 不再使用时,我们会关闭管道
    receivePort.close();
    // 需要将isolate杀死
    isolate?.kill(priority: Isolate.immediate);
  });

  print("main end");
}

void foo(SendPort send) {
  return send.send("Hello Flutter");
}
// 此代码必须在Flutter项目中才能运行
main(List<String> args) async {
  int result = await compute(powerNum, 5);
  print(result);
}

int powerNum(int num) {
  return num * num;
}
上一篇 下一篇

猜你喜欢

热点阅读