ES6系列教程第四篇--asyn详解
一、什么是async
async其实是ES7的才有的关键字,放在这里说,其实是和我们前面所说的Promise,Generator有很大关联的。async的意思是"异步",顾名思义是有关异步操作有关的关键字。下面我们就来构造一个async方法。
async function helloAsync(){return "helloAsync";}console.log(helloAsync())//Promise {<resolved>: "helloAsync"}
申明async方法比较简单,只需要在普通的函数前加上"async"关键字即可。我们执行下这个函数,发现并没有返回字符串"helloAsync",而是通过Promise.resolved()将字符串封装成了一个Promise对象返回。
既然是返回的Promise对象,我们就是用then方法来处理。
async function helloAsync(){return "helloAsync";}helloAsync().then(v=>{console.log(v);//"helloAsync"})
到这,道友们可能纳闷了,就是封装一个Promise的对象返回,这有个毛用啊。别急,await关键字闪亮登场。
二、await关键字
在Generator章节中我们熟悉了yield关键字,yield关键字只能使用在Generator函数中,同样,await关键字也不能单独使用,是需要使用在async方法中。 await字面意思是"等待",那它是在等什么呢?它是在等待后面表达式的执行结果。
function testAwait(){return new Promise((resolve) => {setTimeout(function(){console.log("testAwait");resolve();}, 1000);});}async function helloAsync(){await testAwait();console.log("helloAsync");}helloAsync();
我们来分析下这段代码
1、testAwait()方法中new一个Promise对象返回,promise对象中用setTimeout模拟一个异步过程,即1s后打印"testAwait"。
2、helloAsync()方法中,await testAwait(),表示将阻塞这里,等待testAwait这个异步方法执行并返回结果后,才继续下面的代码。
执行下,1s后打印了下面的日志。
到此,道友们是不是理解了await的作用,就是阻塞主函数的执行,直到后面的Promise函数返回结果。
聪明的道友可能要问,await后面只能 是Promise对象么?答案是否定的,可以是字符串,布尔值,数值以及普通函数。
function testAwait(){setTimeout(function(){console.log("testAwait");}, 1000);}async function helloAsync(){await testAwait();console.log("helloAsync");}helloAsync();
执行结果:
方法没有报错,说明await后面是支持非Promise函数的,但是执行的结果是不一样的,所以await针对所跟的表达式不同,有两种处理方式:
1、对于Promise对象,await会阻塞主函数的执行,等待 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果,然后继续执行主函数接下来的代码。
2、对于非Promise对象,await等待函数或者直接量的返回,而不是等待其执行结果。
我们知道Promise对象有两种状态,除了resolved,还有rejected,我们来看下如果promise对象变为rejected,会如何处理。
function testAwait(){return Promise.reject("error");}async function helloAsync(){await testAwait();console.log("helloAsync");//没有打印}helloAsync().then(v=>{console.log(v);}).catch(e=>{console.log(e);//"error"});
从执行结果看,返回reject状态被外层的catch捕获到,然后终止了后面的执行。
但是在有些情况下,出错后是希望继续执行,而不是中断。对于这种情况可以采用tcy...catch在函数内部捕获异常。
function testAwait(){return Promise.reject("error");}async function helloAsync(){try{await testAwait();}catch(e){console.log("this error:"+e)//this error:error} console.log("helloAsync");//helloAsync}helloAsync().then(v=>{}).catch(e=>{console.log(e);//没有打印});
异常被try...catch捕获后,继续执行下面的代码,没有导致中断。
三、应用场景
上面说到,await可以阻塞主函数,直到后面的Promise对象执行完成。这个特性就能很轻松的解决按顺序控制异步操作,即我们前一章节讲的异步流程的问题。
道友们还记得在Generator章节的肚包鸡的制作过程的实例,我们用async/await来重写这个例子,并比较下两者实现的区别。
//准备function prepare(){return new Promise((resolve) => {setTimeout(function(){console.log("prepare chicken");resolve();},500)}); }//炒鸡function fired(){return new Promise((resolve) => {setTimeout(function(){console.log("fired chicken");resolve();},500)}); }//炖鸡function stewed(){return new Promise((resolve) => {setTimeout(function(){console.log("stewed chicken");resolve();},500)}); }//上料function sdd(){return new Promise((resolve) => {setTimeout(function(){console.log("sdd chicken");resolve();},500)}); }//上菜function serve(){return new Promise((resolve) => {setTimeout(function(){console.log("serve chicken");resolve();},500)});}async function task(){console.log("start task");await prepare();await fired();await stewed();await sdd();await serve();console.log("end task");}task();
这段代码看上去神清气爽,我们来分析下代码:
1、首先每个制作异步过程封装成Promise对象。
2、利用await阻塞原理,实现每个制作的顺序执行。
相比较Generator实现,无需run流程函数,完美的实现了异步流程。
四、总结
从Promise到Generator,再到async,对于异步编程的解决方案越来越完美,这就是ES6不断发展的魅力所在。
上一篇:ES6系列教程第三篇--Generator 详解 下一篇:ES6系列教程第五篇--Class(一)
ES6系列教程第四篇--asyn详解相关推荐
- ES6系列教程第三篇--Generator 详解
一.什么是Generator 函数 先看下面的Generator函数, function* helloGenerator() {console.log("this is generator& ...
- Android系列教程之七:EditText使用详解-包含很多教程上看不到的功能演示
写道 标题有点大,说是详解,其实就是对EditText的一些常用功能的介绍,包括密码框,电话框,空白提示文字等等的讲解,尽量的介绍详细一点,也就是所谓的详解了..呵呵 广告一下我的应用"我团 ...
- 机器学习第四篇:详解决策树算法
01|背景: 我们在日常生活中经常会遇到一些选择需要去做一些选择,比如我们在找工作的时候每个人都希望能找到一个好的工作,但是公司那么多,工作种类那么多,什么样的工作才能算是好工作,这个时候就需要我们对 ...
- eureka集群只注册一个_Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇
Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇 本文主要内容: 1:spring cloud整合Eureka总结 本文是由凯哥(凯哥Java:kagejava ...
- 【NLP】四万字全面详解 | 深度学习中的注意力机制(四,完结篇)
作者 | 蘑菇先生 知乎 | 蘑菇先生学习记 深度学习Attention小综述系列: 四万字全面详解 | 深度学习中的注意力机制(一) 四万字全面详解 | 深度学习中的注意力机制(二) 四万字全面详解 ...
- graphviz 画决策树_数据挖掘入门系列教程(四)之基于scikit-lean决策树处理Iris
数据挖掘入门系列教程(四)之基于scikit-lean决策树处理Iris 加载数据集 数据特征 训练 随机森林 调参工程师 结尾 数据挖掘入门系列教程(四)之基于scikit-lean决策树处理Iri ...
- html5游戏制作入门系列教程(四)
今天,我们继续一系列文章,使用HTML5的canvas组件进行游戏开发.今天我们要学习下元素:声音控制与动画.在我们的演示中,你会 看到一个飞龙.我们会听到持续的翅膀拍打的声音(我们将循环这个声音), ...
- ASP.NET 5系列教程(七)完结篇-解读代码
在本文中,我们将一起查看TodoController 类代码. [Route] 属性定义了Controller的URL 模板: [Route("api/[controller]&quo ...
- OpenCV学习系列教程第五篇:测试和提高代码的效率
Opencv-Python学习系列教程第五篇 来自opencv-python官方学习文档,本人谨做翻译和注释,以及一些自己的理解 本文由作者翻译并进行代码验证,转载请注明出处~ 官方文档请参阅:htt ...
最新文章
- ADAS处理器集成功能安全单片机MCU
- java 中lock,java中lock获取锁的四种方法
- 【廖雪峰python入门笔记】迭代
- 一款图像相关软件PhoXo
- android 开机启动服务。
- 单例模式volatile
- mysqld_multi单机启动多个mysql
- libvirt API管理hypervisors
- 使用知行之桥® EDI系统对接德州仪器TI
- 金盾高级视频加密系统使用教程与经验分享 (金盾视频加密系统跨平台版)
- OpenStack环境下安装Mistral
- win7 计算机定时关机脚本,Win7定时关机命令 win7系统怎么设置定时关机
- 如何启动联想计算机的休眠模式,如何设置休眠、待机、睡眠
- 微信图片去除马赛克_怎么给图片打上马赛克(模糊处理、涂抹)
- Oracle导出表结构(含表名、字段名、数据类型、是否为空、字段说明)至Excel(简单详细)sql语句的形式
- 5大输入法突然下架!得知真相的网友懵了:我都用了10年了……
- Java+SSM+JSP实现医院预约挂号系统
- [java 新手练习1]5x5横排竖排方阵代码(java)
- 算法竞赛入门经典(第2版)—第五章(C++与STL入门)
- Maven ArtifactDescriptorException: Failed to read artifact descriptor for com.sun.mail 异常