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异步笔记的更多相关文章

  1. 09-Node.js学习笔记-异步编程

    同步API,异步API 同步API:只有当前API执行完成后,才能继续执行下一个API console.log('before'); console.log('after'); 异步API:当前API ...

  2. node.js系列笔记之node.js初识《一》

    node.js系列笔记之node.js初识<一> 一:环境说明 1.1 Linux系统CentOS 5.8 1.2 nodejs v0.10.15 1.3 nodejs源码下载地址 htt ...

  3. JS面向对象笔记二

    菜单导航,<JS面向对象笔记一>,  参考书籍:阮一峰之<JavaScript标准参考教程> 一.构造函数和new命令 二.this关键字 三.构造函数和new命令 四.构造函 ...

  4. 【转】Backbone.js学习笔记(二)细说MVC

    文章转自: http://segmentfault.com/a/1190000002666658 对于初学backbone.js的同学可以先参考我这篇文章:Backbone.js学习笔记(一) Bac ...

  5. Node.js学习笔记(2):基本模块

    Node.js学习笔记(2):基本模块 模块 引入模块 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在No ...

  6. Node.js自学笔记之回调函数

    写在前面:如果你是一个前端程序员,你不懂得像PHP.Python或Ruby等动态编程语言,然后你想创建自己的服务,那么Node.js是一个非常好的选择.这段时间对node.js进行了简单的学习,在这里 ...

  7. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  8. JS魔法堂:深究JS异步编程模型

    前言  上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在h ...

  9. Vue.js学习笔记(2)vue-router

    vue中vue-router的使用:

随机推荐

  1. flask-assets使用介绍

    作用:对css.js静态文件进行打包,打包成一个文件,然后去除文件里的换行.空行等进行压缩: 而且 Flask-Assets 还会使用特定的 HTTP Response Header, 让浏览器缓存这 ...

  2. Shell--数据流重定向

    数据流重定向就是将某个命令执行后应该要出现在屏幕上的数据传输到其他地方 标准 1.标准输入(stdin):代码为0,使用<或<< 2.标准输出(stdout):代码为1.,使用> ...

  3. vue-resource基本使用方法

    一.vue-resource特点 1.体积小:vue-resource非常小巧,在压缩以后只有大约12KB,服务端启用gzip压缩后只有4.5KB大小,这远比jQuery的体积要小得多. 2.支持主流 ...

  4. extjs4权限管理,actioncolumn列显示隐藏或禁用

    //隐藏getClass: function(v, meta, rec) { if ( someCondition ) { return 'x-hidden' } }//加入其他样式getClass: ...

  5. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-人机界面快速入门 TC2

    创建最简单的静态文本,就像是label,就只需要绘制一个矩形框,然后填写Text,取消边框即可(你也可以设置自定义字体)   创建动态的文本框,就像是textbox,需要设置这个矩形框的Text为%d ...

  6. 野哥点评了Facebook、Amazon、Google、微软和苹果

    娱乐一下.我们来比較一下4家相似的科技公司的软件政治观. (1)Facebook-诊断:极端自由. Facebook的规模已经非常大了.可他们的行为处事仍然像是一家创业公司.并且到眼下为止似乎也活得挺 ...

  7. 利用问答机器人API开发制作聊天类App

    缘起 很久没写项目了,所以单纯的想练练手,正好看到有问答机器人的接口,想到之前也做过聊天项目,为什么不实验一下呢.当然也是简单调用接口的项目,并没有真正的完成问答的算法等等.业余项目,功能不齐全,只实 ...

  8. lodash kebabCase

    _.kebabCase([string='']) 转换字符串为 kebab case. _.kebabCase('Foo Bar'); // => 'foo-bar' _.kebabCase(' ...

  9. 在ASP.NET MVC中支持 HttpHandler

    写HttpHandler与ASP.NET WebForm基本没有什么不同.只是部署的时候需要注意,只在Web.config中注册还不行,需要在Global.asax.cs添加一条ignore规则: p ...

  10. mongoDB 高级查询之复杂查询$where

    http://blog.csdn.net/drifterj/article/details/7833883