JS异步笔记
Promise
最早接触异步是在.net中,当时还是比较流行使用基于控件的BackgroundWorker
,其自身通过子线程的方式来异步处理一些情况,并且封装了一些功能与主线程通信。后来,开始使用Thread,再后来,因为Thread的性能与生成数量的不可控,使用了ThreadPool,再后来,出现了Task,随后async、await如发而至。在理解了async和await之后不久,es2015便为js也带来了Promise,以解决在js中大量的callback的问题(说实话,不层数不多的情况下,用callBack还是很爽的,可能年纪大了,思维有些固守了)。Promise使得无处不在的callBack得到了控件,阅读追踪代码也终于变得方便了。
关于Promise,可以参考其白皮书https://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects
,在MDN上,给出的使用方法是
var DoWork=new Promise( function(resolve, reject) {...} /* executor */ );
,其中,resolve和reject也是回调函数(callback),并且在{...}的语法块中,如果一切正常则调用resolve回调方法返回,如果有问题,则调用reject回调方法返回。这像极了原来的回调方式(如function DoWork(SuccessCallBack,ErrorCallBack){...}。但是,其最大的特点则在于,返回的并不是function
了,而是一个Promise
对象,这也为以后的await的加入铺好了路。同样,在调用的时候,语法糖也甜得很。
原本DoWork的调用方法:
DoWork(()=>{alert("success");},err=>{ alert("fail");});
新的调用方法:
DoWork().then(()=>{alert("success");}).catch(err=>{alert(err);});
想来,聪明的你,并没有发现这种用法的场景中,有何优势。当然,优势还是有的,比较在使用Promise.All()函数的时候,则可以使得多个并发任务同时执行,只有在每一个任务都完成的情况下,才执行then的后续方法。另外,写法上,将之前的内层嵌套改为现在的外层用.的链式调用,在美观和可读性上,提升了不少,还有其它一些优势,这里就不多说了,因为今天Promise不是主角,它只是主角的爹妈,,而主角则是async/await
。
async/await
做了这么多年的c#开发,微软给我的最大感觉的就是,语法糖真的甜。之前遇到一个微信的开发框架Senparc.Weixin SDK
也是同样的开发理念,说实话,真的好,能让开发人员少写一行就绝不让多写一行,能让开发人员少动脑子就不让其多动脑子,这样,可以有更大的精力放在处理业务以及构造程序逻辑关系上。js的`async/await和.net的非常像,这里就不说.net了,只说js中
async/await`的用法。
对于async/await
(打起来好烦,下文就用aa表示了(冰魂:……))来说,它最大的优势在于,可以以同步代码的方式来实现异步,并且与人的自然认识非常的吻合。
举个例子:
1、给小明钱。
2、让小明去超市买西瓜,如果有西瓜就买回来,如果没有,则买苹果,如果苹果也没有,就把钱还给我。
3、给小丽个椅子。
4、让小丽在这儿看电视。
var XiaoMingGoToMarket = return Promise(resolve,reject=>{
setTimeout(()={
if(有西瓜()){
resolve("买了西瓜");
}else if(有苹果()){
resolve("买了苹果");
}else{
reject("啥也没买,钱还给你吧");
}
},5*1000);//五分钟后到超市
async function MakeXiaoMingToMarket(){
console.log("知道了,现在就准备去超市");
try{
var 买的水果= await XiaoMingGoToMarket();
console.log("买到了"+买的水果);
}catch(err){
console.log("啥也没买到,"+err);
}
}
console.log('1、给小明钱');
console.log("2、让小明去超市买西瓜,如果有西瓜就买回来,如果没有,则买苹果,如果苹果也没有,就把钱还给我");
MakeXiaoMingToMarket();
console.log('3、给小丽个椅子。');
console.log('4、让小丽在这儿看电视。');
以上代码,先不看XiaoMiGoToMarket
这个定义,下面的五行代码就非常的接近人的思维,其主体是我,我在一件件的下命令,至于客体要怎么做,什么时候去做我不管。对于我来讲,这五行代码是同步的,有严格的先后顺序,因为“我”下命令本身就是有先后的。但是,在我下指令给小明让小明去做事情 的时候,它去超市这段在路上的时间,是异步的。所以,对于小明来说,他的事情分为三部分(不考虑回来的事情):1、接收我的指令。2、走在路上(比较耗时)。3、到了超市买东西并告诉我结果。其中,接收我的指令是与我直接相关的,我需要知道他是否真的接收到我的指令了,所以,与我是同步的。在他接收到我的指令之后 ,我再给小丽一个椅子(不然,估计我就自己亲自去买了)。这是小明的第一部分做的事情,其第二部分,则是await那一句,那一句,则是产生异步的开始,await其实就是小明去买水果了,同时,离开我的视线,我与他的同步关系也就断开了,我开始“给小丽个椅子”了,然后继续做我自己的事情。至于小明,等他的await的事情(去超市买东西)完成了之后,他会接着await下面的语句,将下面的事情做完。
大概就是这么个过程,其实原理很简单。
就是:
1、async function会被拆成两份,以await语法分开,之前一部分(不包含await本身),我们称它为PreWork,之后一部分我们你之为AftWork。
2、PreWork是同步代码,要非async的function中的代码一样,与调用函数同步。
3、当函数插到await,即AftWork代码时,因为await后面跟着的是Promise,所以,此时,异步执行Promise,同时,将AftWork打包为一个函数,放在旁边。同时,调用方法的执行焦点,从async function中返回,继续去执行自己的代码。
4、当await后面的Promise执行完成后,如果其内部调用了resolve,则执行之前放在旁边的由AftWork打包的一个临时函数。如果其内部调用了reject,则在await这一句这儿,向外抛出一个异常,其异常内容为reject(err)时其参数的内容。
JS异步笔记的更多相关文章
- 09-Node.js学习笔记-异步编程
同步API,异步API 同步API:只有当前API执行完成后,才能继续执行下一个API console.log('before'); console.log('after'); 异步API:当前API ...
- node.js系列笔记之node.js初识《一》
node.js系列笔记之node.js初识<一> 一:环境说明 1.1 Linux系统CentOS 5.8 1.2 nodejs v0.10.15 1.3 nodejs源码下载地址 htt ...
- JS面向对象笔记二
菜单导航,<JS面向对象笔记一>, 参考书籍:阮一峰之<JavaScript标准参考教程> 一.构造函数和new命令 二.this关键字 三.构造函数和new命令 四.构造函 ...
- 【转】Backbone.js学习笔记(二)细说MVC
文章转自: http://segmentfault.com/a/1190000002666658 对于初学backbone.js的同学可以先参考我这篇文章:Backbone.js学习笔记(一) Bac ...
- Node.js学习笔记(2):基本模块
Node.js学习笔记(2):基本模块 模块 引入模块 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在No ...
- Node.js自学笔记之回调函数
写在前面:如果你是一个前端程序员,你不懂得像PHP.Python或Ruby等动态编程语言,然后你想创建自己的服务,那么Node.js是一个非常好的选择.这段时间对node.js进行了简单的学习,在这里 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- JS魔法堂:深究JS异步编程模型
前言 上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在h ...
- Vue.js学习笔记(2)vue-router
vue中vue-router的使用:
随机推荐
- 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:3.安装Oracle RAC-3.2.安装 cvuqdisk 软件包
3.2.安装 cvuqdisk 软件包 3.2.1. 准备Oracle Grid安装包 上传Grid .Oracle 安装文件: sftp> put E:\Software\linux.x64 ...
- Discuz! 6.x/7.x 全局变量防御绕过漏洞
受影响产品: Discuz! 6.x/7.x 漏洞描述: 由于php5.3.x版本里php.ini的设置里request_order默认值为GP,导致Discuz! 6.x/7.x 全局变量防御绕过漏 ...
- JAMon监控SQL执行时间
JAMon监控web工程方法的调用性能 http://www.cnblogs.com/zfc2201/p/3786365.html 这往往篇文章主要告诉大家如何监控web方法调用时间,在这个基础这上, ...
- 【C++ OpenGL ES 2.0编程笔记】8: 使用VBO和IBO绘制立方体 【转】
http://blog.csdn.net/kesalin/article/details/8351935 前言 本文介绍了OpenGL ES 2.0 中的顶点缓冲对象(VBO: Vertex Buff ...
- GLSL使用FBO实现MRT(Multiple Render Targets)绘制到多张纹理 【转】
项目的程序里设计需要将某一帧渲染出来的画面拆成三通道单色图像存到三张纹理里面.要绘制到纹理里,自然就想到FBO了.但是一次要输出多张纹理,这个还没接触过.一阵网上搜索过后,终于了解到了MRT(多重渲染 ...
- List<实体>与List<String>数据互转
1.List<实体>数据: public List<Device> queryOSDevice(String cpu,String ip,String name){ Strin ...
- ubuntu中wifi显示被硬件禁用的解决方法
本人使用的电脑是华硕X550C,安装了ubuntu16.04版本. 联网的时候显示“wifi已经通过硬件开关禁用”.按Fn+F2无法开启wifi.通过rfkill命令无法也无法开启wifi. 经过了解 ...
- poj 3468 A Simple Problem with Integers 线段树区间更新
id=3468">点击打开链接题目链接 A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072 ...
- IE8兼容<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
转自:http://nicyea.iteye.com/blog/719007 前言 X-UA-Compatible是针对ie8新加的一个设置,对于ie8之外的浏览器是不识别的,这个区别与 conten ...
- ajax乱码解决总结
第一,javascript沿用java的字符处理方式,内部是使用unicode来处理所有字符的,第二,utf-8是每个汉字(unicode字符)用3个字节来存储.第三,用utf-8来send数据是不会 ...