likes
comments
collection
share

Flutter网络

作者站长头像
站长
· 阅读数 33

1、获取测试数据

2、集成网络请求工具

  • Dart库
  • pubspec.yaml文件,cupertino_icons: 中贴入库名与版本号,Pub get即可

3、模型转换

3.1、Map转Json

  • json.encode(value);

3.2、Json转Map

  • json.decode(value); Flutter网络

3.3、创建特定模型(传参,返回特定值)

Flutter网络

4、异步

  • 多线程是包含A、B、C多个进程,异步是A进程下a、b、c任务
  • 定义的方法后加async,耗时操作前加await表示等待耗时操作结束后再进行下一步。
  • Dart规定async标记的异步函数,只能由await来调用,不加await则按同步函数顺序执行
  • 常见异步操作:
    • 通过网络获取数据。
    • 写入数据库。
    • 从文件读取数据。 Flutter网络

4.1、Future

  • 未来获取数据,内部已经被包装成异步的,单独使用时加不加async没影响

  • await:设置等待Future包装的任务完成后,再执行下边代码,与async搭配使用 Flutter网络

    • 后边任务必须是异步才能用await修饰
    • 当前函数也必须是异步函数
    • 会阻塞后边所有代码执行,如果该函数中还有要先执行的其他代码则可不用await,而改用.then(value) => 待耗时操作结束后执行的代码
  • .then(value)中的valueFuture内最终return的值,但如果有异常,那么.then()不执行 Flutter网络

4.1.1、.then(类型 value) {代码}.catchError((errorMessage){代码}).whenComplete((){代码}).timeout(Duration(seconds: 1));
  • 不初始化直接链式调用 Flutter网络

  • 初始化后对实例链式调用 Flutter网络

  • 一个任务一个任务的执行 Flutter网络

  • 多个Future都完成后再执行 Flutter网络

  • ,onError:(){}.catchError()区别:

    • .catchError回调只处理原始Future抛出的错误,不能处理回调函数抛出的错误
    • onError只能处理当前Future的错误
    • onError(){} 一次就结束,.catchError() 是链式,可多次使用
4.1.2、Future.value()
  • 创建一个返回指定value值的Future:
    void testFuture() async {
        var future = await Future.value(1);
        print("future value: $future.");
    }
    testFuture();
    
    打印结果:
    1
    
4.1.3、Future.delayed()
  • 创建一个延迟执行的Future:
    void testFuture() async {
      Future.delayed(Duration(seconds: 2), () {
        print("delayed 2秒.");
      });
    }
    testFuture();
    
    打印结果:
    (2秒后打印)delayed 2
    
4.1.4、Future.timeout()
  • 设置超时时限,本来Future会在2s后完成,但是timeout声明的是1s后超时,所以1s后Future会抛出TimeoutException:
    void testFuture() async {
        new Future.delayed(new Duration(seconds: 2), () {
          return 1;
        }).timeout(new Duration(seconds:1)).then(print).catchError(print);
    }
    testFuture();
    
    打印结果:
    TimeoutException after 0:00:01.000000: Future not completed
    
4.1.5、Future.forEach()
  • 根据某个集合对象,创建一系列的Future。并且会按顺序执行这些Future
    void testFuture() async {
        Future.forEach({1,2,3}, (num){
          return Future.delayed(Duration(seconds: num),(){
              print("$num");
          });
        });
    }
    testFuture();
    
    打印结果:
    (在1秒后)1
    (再2秒后)2
    (再3秒后)3,总时间为6
    
4.1.6、Future.any()
  • 返回第一个执行完的Future结果,不管这个结果是正确的还是error:
    void testFuture() async {
      Future.any([1, 2, 5].map((delay) => new Future.delayed(new Duration(seconds: delay), () => delay)))
        .then(print)
        .catchError(print);
      }
    testFuture();
    
    打印结果:
    1
    
4.1.7、Future.doWhile()
  • 重复执行某个动作,直到返回false或者Future才退出循环,适用于一些递归操作场景:
    void testFuture() async {
        var random = new Random();
        var totalDelay = 0;
        Future.doWhile(() {
            if (totalDelay > 10) {
              print('total delay: $totalDelay秒');
              return false;
            }
            var delay = random.nextInt(5) + 1;
            totalDelay += delay;
            return new Future.delayed(new Duration(seconds: delay), () {
              print('等 $delay 秒');
              return true;
            });
        }).then(print).catchError(print);
    }
    testFuture();
    
    打印结果:
    5
    5
    3
    total delay: 11
    null
    4
    3
    total delay: 12
    null
    
4.1.8、Future.sync()
  • 会同步执行其入参函数,然后调度到microtask queue来完成自己。也就是一个阻塞任务,会阻塞当前代码,sync的任务执行完了,代码才能走到下一行:
    void testFuture() async {
        Future((){
            print("1");
        });
        Future.sync(() {
            print("sync microtask 2");  //return Future(() {print("2");
        });
        Future((){
            print("3");
        });
        Future.microtask((){
            print("microtask");
        });
    }
    testFuture();
    print("主队列");
    
    结果:
    sync microtask 2
    主队列
    microtask
    1
    3
    
  • 但如果上边sync()中改成return一个Future:则sync变成普通Future,打印顺序1、2、3
4.1.9、Future.microtask
  • 创建一个在microtask queue运行的Future。我们知道microtask queue的优先级是比event queue高的。而一般Future是在event queue执行的。所以Future.microtask创建的Future会优先于其他Future执行:
    void testFuture() async {
        Future((){
            print("1");
        });
        Future((){
            print("2");
        });
        Future.microtask((){
            print("microtask");
        });
    }
    testFuture();
    
    打印结果:
    microtask
    1
    2
    
4.1.10、Future.wait()
  • 等待多个Future完成,并收集它们的结果,有两种情况:
    1. 所有Future都有正常结果返回。则Future的返回结果是所有指定Future的结果的集合:
      void testFuture() async {
          var future1 = new Future.delayed(new Duration(seconds: 1), () => 1);
          var future2 = new Future.delayed(new Duration(seconds: 2), () => 2);
          var future3 = new Future.delayed(new Duration(seconds: 3), () => 3);         
      
          Future.wait({future1,future2,future3}).then(print).catchError(print);
      }
      testFuture();
      
      打印结果:
      [1, 2, 3]
      
    2. 其中一个或者几个Future发生错误,产生了error。则Future的返回结果是第一个发生错误的Future的值:
      void testFuture() async {
          var future1 = new Future.delayed(new Duration(seconds: 1), () => 1);
          var future2 = new Future.delayed(new Duration(seconds: 2), () {
            throw 'Future发生错误啦!';
          });
          var future3 = new Future.delayed(new Duration(seconds: 3), () => 3);
      
          Future.wait({future1,future2,future3}).then(print).catchError(print);
      }
      testFuture();
      Future发生错误啦!
      打印结果:
      

4.2、FutureBuilder

  • 异步渲染,最终内部要return一个widget
  • 不复杂界面使用效率高,不需要对状态、数据进行存储
4.2.1、snapshot.connectionState
  • 异步渲染状态 Flutter网络
4.2.2、snapshot.data
  • 异步渲染数据 Flutter网络

4.3、scheduleMicrotask(callback):微任务

  • Flutter有两种队列,一个是事件队列,一个是微任务队列,微任务队列优先级高于事件队列 Flutter网络
  • .then() 其实也是微任务,Future加载后将.then()加入微任务队列,所以优先级很高

注:

  • sleep()会阻塞主线程

5、多线程

5.1、特点与对比异步

  • 异步是单线程的,Flutter多线程更类似于多进程,因为各线程有独立的内存空间
  • 因为内存独立,所以无法直接调用修改,也没有抢占资源的问题,因此没有锁!

5.2、修改内容

5.2.1、Isolate:隔离
  • 因为内存独立,将内部与外部隔离,因此修改内容需要通讯
  • 使用后,端口要关闭线程要kill Flutter网络
  • ReceivePort(); 创建端口
  • Isolate.spawn(func,port); 创建线程,执行一个将端口作为参数的方法
  • port.listen((message){代码}); 监听端口内容
  • port.send(message); 发送端口内容
5.2.2、compute(func,param)
  • 可以直接接收子线程的变量
  • 内部是对Isolate的封装,在compute(func,param)中修改外部变量不生效 Flutter网络
注意:Future与线程结合

Flutter网络

  • 拿到return看一下: Flutter网络

6、状态保持

  • 混入AutomaticKeepAliveClientMixinFlutter网络

这篇Cat的Dart异步编程对原理解析的更详细,有兴趣的可以看一下

个人总结,仅供参考

转载自:https://juejin.cn/post/7031508106739712031
评论
请登录