美文网首页
Flutter踩坑记录-future sync以及await

Flutter踩坑记录-future sync以及await

作者: 曾勇浩_7f31 | 来源:发表于2020-06-06 02:38 被阅读0次

async

任何一个GUI开发者都明白一个朴素的道理-"不能在UI线程中进行耗时的操作"

为此,我们总是在学习任何一门前端架构的时候,总会不自觉的首先去思考,该语言或者框架是如何进行异步操作的,诸如网络操作,IO操作等,而进行异步操作之后,我们如何拿到数据,或者又怎么解决并发问题,这都是一门前端语言基本的元素。

flutter中,通俗的讲,其线程模型是单线程的,我们无需进行线程的申明,并管理其并发状态,这一点要比java开发简单许多。

但这只是一种方便开发者的机制,开发者并不能违背基本的原则,也就是不能直接执行一个阻塞操作,我们还是需要将耗时操作进行异步申明。

在Dart中,我们在可以方法中申明 sync关键字 来表示这是一个异步方法。伪代码如下

  getDate() async {
           delayed(5).callback(
             print("test2")
           
           )
  }
  
  getDate();
  print("test1")

在方法后面加上sync关键字 此时 该函数将不会阻塞 打印结果为 test1然后5秒之后打印test2

这是一个很简单的例子,但也确实是Dart中大部分异步方法的书写方式,剩下的所有操作,都将以async为基础

*await

有时候,我们需要依靠异步结果的返回,来进行某些操作,比如嵌套的网络请求,在获取第一个结果之后进行第二次操作,伪代码如下。

      getData() async{
           delayedTask(5).callback(value){
            getData2();
           }
      }

这只是两层的嵌套使用而已,在回调中嵌套一个另一个异步操作,但是如果嵌套的多了呢?

      getData() async{
           await delayedTask(5).callback(data1){
            getData2(data1).callback(data2){
             getData3(data2).callback(data3){
                 .....
             }  
            }
           }
      }

实际的代码将比这更加复杂,我们陷入了回调地狱

为了避免这种情况,Dart提供了 await 关键字,顾名思义,等待,等待一个异步操作的完成。

我们将代码修改一下

      getData() async{
          var result1 = await delayedTak(5)
          var result2 = await getData2(result1);
          ......
         
      }

在异步代码块之前设置 await关键字 表示等待这个任务完成在进行下一段代码执行。

必须要注意 await关键字必须在 async函数中调用,编辑器将提示这一点。

await的另一点需要注意的是,调用await的地方 也必须是await的 否则 await关键字将无效,代码依旧是异步执行。 既然我等待了,那你也必须等待。像极了等女朋友化妆的你。

      getData() async{
          var result1 = await delayedTak(5)
          var result2 = await getData2(result1);
          ......
         
      }
      
      main() async{
          await getData();
      }
      

使用 await关键字可以避免回调地狱。

future

我们已经知道如何标记一个函数是async函数,但事实上,我们必须得实际创建一段异步操作,就如同java中,new一个Thread()之后 还需要放一个Runable()

Dart中,我们使用future来表明一段异步任务,future的意思是未来,也就是未来会发生的事儿。

上面的代码 实际上应该这样写

     Future<String> getData() async{
        return  Future.delayed(const Duration(seconds: 5), () => "test");
         
         
      }
      
      main() {
          var Future<String> result =  getData();
      }
      

当你的函数加入 async之后 函数返参就固定为Future了
我们在main方法中得到这个future函数

此时异步代码并没有真正的执行,他们还处在未来的某一刻,我们需要开始观察这个future,他才会开始工作

     Future<String> getData() async{
        return  Future.delayed(const Duration(seconds: 5), task => "test");
         
         
      }
      
      main() {
          var Future<String> future =  getData();
          future.then(result){
              print(result)
          }
      }
      

调用future的then方法来获取task返回的数据,这其实就是观察者模式的一种实现。

当然 结合我们上面讲的 当我们将future前面加入 await的话 我们就可以直接拿到返回数据了

     Future<String> getData() async{
        return  Future.delayed(const Duration(seconds: 5), task => "test");
         
         
      }
      
      main() async{
        var result = await getData();
        print(reslut)
      }
      

打印结果同样是"test"

async await 和future 这几乎是Dart里异步的基本操作方法了。

下次我们来讲如何在widget树中对future进行监听,以及如何转换future

相关文章

网友评论

      本文标题:Flutter踩坑记录-future sync以及await

      本文链接:https://www.haomeiwen.com/subject/ikhttktx.html