当前位置: 首页 > news >正文

怎么做网站游戏网站优化招商

怎么做网站游戏,网站优化招商,vps网站管理软件,企业建设网站的意义由于前面的HTTP请求用到了异步操作,不少小伙伴都被这个问题折了下腰,今天总结分享下实战成果。Dart是一个单线程的语言,遇到有延迟的运算(比如IO操作、延时执行)时,线程中按顺序执行的运算就会阻塞&#xf…

由于前面的HTTP请求用到了异步操作,不少小伙伴都被这个问题折了下腰,今天总结分享下实战成果。Dart是一个单线程的语言,遇到有延迟的运算(比如IO操作、延时执行)时,线程中按顺序执行的运算就会阻塞,用户就会感觉到卡顿,于是通常用异步处理来解决这个问题。当遇到有需要延迟的运算(async)时,将其放入到延迟运算的队列(await)中去,把不需要延迟运算的部分先执行掉,最后再来处理延迟运算的部分。

async和await

首先看一个案例:

new Future.delayed(const Duration(seconds: 3),
//                    () => Navigator.of(context).pop(Constants.baseActionList[item]));

然后我们调用这个函数,想获取其结果:

 String data = getData();

在书写时,在IDE中这个代码是没有问题的,但是当我们运行这段代码时,就报错了:

为什么呢?因为dataString类型,而函数getData()是一个异步操作函数,其返回值是一个await延迟执行的结果。在Dart中,有await标记的运算,其结果值都是一个Future对象,Future不是String类型,所以就报错了。

那如果这样的话,我们就没法获取到延迟执行的结果了?当然可以,Dart规定有async标记的函数,只能由await来调用,比如这样:

String data = await getData();

但是要使用await,必须在有async标记的函数中运行,否则这个await会报错:

于是,我们要为这个给data赋值的语句加一个async函数的包装:

String data;
setData() async {data = await getData();    //getData()延迟执行后赋值给data
}
上面这种方法一般用于调用封装好的异步接口,比如getData()被封装到了其他dart文件,通过使用async函数对其调取使用

再或者,我们去掉async函数的包装,在getData()中直接完成data变量的赋值:

String data;
getData() async {data = await http.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});     //延迟执行后赋值给data
}

这样,data就获取到HTTP请求的数据了。就这样就完了?是滴,只要记住两点:

  • await关键字必须在async函数内部使用
  • 调用async函数必须使用await关键字
PS:await关键字真的很形象,等一等的意思,就是说,既然你运行的时候都要等一等,那我调用的时候也等一等吧

Future简单科普

前面个讲到过,直接return await ...的时候,实际上返回的是一个延迟计算的Future对象,这个Future对象是Dart内置的,有自己的队列策略,我们就来聊聊这个Future。

先啰嗦一些关于Dart在线程方面的知识。

Dart是基于单线程模型的语言。在Dart也有自己的进程(或者叫线程)机制,名叫isolate。APP的启动入口main函数就是一个isolate。玩家也可以通过引入import 'dart:isolate'创建自己的isolate,对多核CPU的特性来说,多个isolate可以显著提高运算效率,当然也要适当控制isolate的数量,不应滥用,否则走火入魔自废武功。有一个很重要的点,Dart中isolate之间无法直接共享内存,不同的isolate之间只能通过isolate API进行通信,当然本篇的重点在于Future,不展开讲isolate,心急的小伙伴可以参考官方阅读理解或者参考大神tain335的人肉翻译。

Dart线程中有一个消息循环机制(event loop)和两个队列(event queuemicrotask queue)。

  • event queue包含所有外来的事件:I/O,mouse events,drawing events,timers,isolate之间的message等。任意isolate中新增的event(I/O,mouse events,drawing events,timers,isolate的message)都会放入event queue中排队等待执行,好比机场的公共排队大厅。
  • microtask queue只在当前isolate的任务队列中排队,优先级高于event queue,好比机场里的某个VIP候机室,总是VIP用户先登机了,才开放公共排队入口。

如果在event中插入microtask,当前event执行完毕即可插队执行microtask。如果没有microtask,就没办法插队了,也就是说,microtask queue的存在为Dart提供了给任务队列插队的解决方案。

main方法执行完毕退出后,event loop就会以FIFO(先进先出)的顺序执行microtask,当所有microtask执行完后它会从event queue中取事件并执行。如此反复,直到两个队列都为空,如下流程图:

注意:当事件循环正在处理microtask的时候,event queue会被堵塞。这时候app就无法进行UI绘制,响应鼠标事件和I/O等事件。胡乱插队也是有代价的~

虽然你可以预测任务执行的顺序,但你无法准确的预测到事件循环何时会处理你期望的任务。例如当你创建一个延时1s的任务,但在排在你之前的任务结束前事件循环是不会处理这个延时任务的,也就是或任务执行可能是大于1s的。

OK,了解以上信息之后,再来回到Future,小伙伴可能已经被绕晕了。

Future就是event,很多Flutter内置的组件比如前几篇用到的Http(http请求控件)的get函数、RefreshIndicator(下拉手势刷新控件)的onRefresh函数都是event。每一个被await标记的句柄也是一个event,每创建一个Future就会把这个Future扔进event queue中排队等候安检~

什么?那microtask呢?当然不会忘了这个,scheduleMicrotask,用法和Future基本一样。

为什么要用Future?

前面讲到,用asyncawait组合,即可向event queue中插入event实现异步操作,好像Future的存在有些多余的感觉,刚开始我本人也有这样的疑惑,且往下看。

当定义Flutter函数时,还可以指定其运行结果返回值的类型,以提高代码的可读性:

//定义了返回结果值为String类型
Future<String> getDatas(String category) async {var request = await _httpClient.getUrl(Uri.parse(url));  var response = await request.close();return await response.transform(utf8.decoder).join();
}run() async{int data = await getDatas('keji');    //因为类型不匹配,IDE会报错
}

Future最主要的功能就是提供了链式调用。熟悉ES6语法的小伙伴乐开了花,链式调用解决两大问题:明确代码执行的依赖关系和实现异常捕获。WTF?还不明白?且看下面这些案例:

//案例1
funA() async{...set an important variable...
}funB() async{await funA();...use the important variable...
}main() async {funB();   
}
//如果要想先执行funA再执行funB,必须在funB中await funA();
//funB的代码与funA耦合,将来如果funA废掉或者改动,funB中还需要经过修改以适配变更。//案例2
funA() async{try{...set an important variable...}catch(e){do sth...}finally{do sth. else...}
}funB() async{try{...use the important variable...}catch(e){do sth...}finally{do sth. else...}
}main() async {await funA();await funB();
}
//没有明确体现出设置变量和使用变量之间的依赖关系,其他开发者难以理解你的代码逻辑,代码维护困难
//并且如果为了防止funA()或者funB()因发生异常导致程序崩溃
//要到funA()或者funB()中分别加入`try`、`catch`、`finally`

为了解决上面的问题,Future提供了一套非常简洁的解决方案:

//案例3
 funA(){...set an important variable...    //设置变量
}funB(){...use the important variable...   //使用变量
}
main(){new Future.then(funA()).then(funB());   // 明确表现出了后者依赖前者设置的变量值new Future.then(funA()).then((_) {new Future(funB())});    //还可以这样用//链式调用,捕获异常new Future.then(funA(),onError: (e) { handleError(e); }).then(funB(),onError: (e) { handleError(e); })  
}

案例3的玩法是asyncawait无法企及的,因此掌握Future还是很有必要滴。当然了,Future的玩法不仅仅局限于案例3,还有很多有趣的玩法,包括和microtask对象scheduleMicrotask配合使用,我这里就不一一介绍了,大家参考大神tain335的人肉翻译或者官网阅读理解吧。

总结

Dart的isolate中加入了event queuemicrotask queue后,有了一点协程的感觉,或许这就是Flutter为啥在性能上敢和原生开发叫板的原因之一吧。本篇的内容比较抽象,如果还是有不明白的小伙伴,欢迎留言提问,我尽量回答,哈哈哈,就酱,欢迎加入到Flutter圈子或flutter 中文社区(官方QQ群:338252156),群里有前后端及全栈各路大神镇场子,加入进来没事就写写APP挣点外快(这个真的有),顺便翻译翻译官方英文原稿拉一票粉丝,一举多得何乐而不为呢。

 

转载于:https://www.cnblogs.com/zhujiabin/p/10213694.html

http://www.lbrq.cn/news/2727235.html

相关文章:

  • 做logo什么网站seo快排技术教程
  • 建设银行中国网站软件推广平台有哪些?哪个比较好
  • 创意产品设计网站推荐品牌运营包括哪些内容
  • 网站建设webmeng今日深圳新闻最新消息
  • 做网站 网上接单15个常见关键词
  • 海口专业网站制作策划百度seo白皮书
  • h3c路由器怎么做网站映射如何进行网络推广和宣传
  • 陕西省建设八大员官方网站网站建设黄页免费观看
  • 可以做样机图的网站seo线上培训班
  • 公司网站制作注意什么卡一卡二卡三入口2021
  • 网站如何做长尾词排名谷歌广告联盟官网
  • 品牌的佛山网站建设怎么找拉新推广平台
  • 如何自己做门户网站益阳网站seo
  • 建站快车官网如何做百度关键词推广
  • 找公司做网站注意事项优化系统的软件
  • 安微省建设厅网站seo推广优化外包公司
  • 个人备案能做什么网站电商培训有用吗
  • 网站访问量大打不开舆情视频
  • 用php做动态网站google海外推广
  • 微信做兼职什么网站好6个好用的bt种子搜索引擎
  • 手机wap网站制作免费最全的百度网盘搜索引擎
  • 网站怎么做适配谷歌网站网址
  • 营口网站开发建网站哪个平台好
  • 网站制作样板网站seo检测
  • 网站怎么做隐藏内容seo和sem的联系
  • 郑州最近新闻事件汕头seo快速排名
  • 西安谁家做网站湖南seo
  • 网站建设教育类旧式网站seo网络推广是什么意思
  • 做黄页网站要告我上海百度搜索优化
  • 万江区网站仿做北京seo优化厂家
  • Vue2与Vue3生命周期函数全面解析:从入门到精通
  • QT在Widget类下的四种QPushbutton的信号与槽的连接方式
  • 【Golang】:数据类型
  • Go语言中安全停止Goroutine的三种方法及设计哲学
  • Mybatis学习笔记(七)
  • 搭建局域网yum源仓库全流程