koa2第一天 async详解
一、什么是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不断发展的魅力所在。
---------------------
作者:恰恰虎
来源:CSDN
原文:https://blog.csdn.net/tcy83/article/details/80544048
版权声明:本文为博主原创文章,转载请附上博文链接!
koa2第一天 async详解的更多相关文章
- 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳
学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 ...
- (四)、 nodejs中Async详解之一:流程控制
为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程控制:简化十种 ...
- Async详解之一:流程控制
为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程控制:简化十种 ...
- Async 详解
一:流程控制 为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程 ...
- nodejs Async详解之三:集合操作
Async提供了很多针对集合的函数,可以简化我们对集合进行异步操作时的步骤.如下: forEach:对集合中每个元素进行异步操作 map:对集合中的每个元素通过异步操作得到另一个值,得到新的集合 fi ...
- nodejs中Async详解之一:流程控制
为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程控制:简化十种 ...
- springBoot服务整合线程池ThreadPoolTaskExecutor与@Async详解使用
ThreadPoolExecutor:=======这个是java自己实现的线程池执行类,基本上创建线程池都是通过这个类进行的创建.ThreadPoolTaskExecutor:========这个是 ...
- 【转】apue《UNIX环境高级编程第三版》第一章答案详解
原文网址:http://blog.csdn.net/hubbybob1/article/details/40859835 大家好,从这周开始学习apue<UNIX环境高级编程第三版>,在此 ...
- Node.js中Async详解:流程控制
安装 npm install async --save 地址 https://github.com/caolan/async Async的内容主要分为三部分 流程控制: 简化九种常见的流程的处理 集合 ...
随机推荐
- Bell数
事实上,\[e^{(e^t-1)x}=\sum_{k=0}^{\infty}\frac{B_k(x)}{k!}.\]\[B_n(x)=x\sum_{k=1}^{n}\binom{n-1}{k-1}B_ ...
- Python GUI编程(TKinter)(简易计算器)
搞课设搞得心累,现在看到人脸这两个字就烦躁,无聊搞搞tkinter,实现一个计算器的功能,能够简单的加减乘除. 简单的页面如下: 简单的代码如下: # encoding:utf-8 import tk ...
- Git本地仓库的使用
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git 与 SVN 区别点: 1.Git 是分布式的,SVN 不是:这是 Git 和其它非分布式的版本控制系统,例如 S ...
- 【Linux远程连接工具】Xshell、Xftp家庭/学生版(免费使用)
注:Xshell.Xftp家庭/学生版无需激活,可以免费使用! 1.步骤一: 官网下载地址:https://www.netsarang.com/zh/ 选择[所有下载]->[家庭/学校免费] ...
- Canvas如何绘制精美的图?
一.Canvas的基本使用 首先在使用Canvas一般先在<body>中添加: <canvas id="></canvas> 然后使用Js进行获取canv ...
- MySQL数据库渗透及漏洞利用总结
Mysql数据库是目前世界上使用最为广泛的数据库之一,很多著名公司和站点都使用Mysql作为其数据库支撑,目前很多架构都以Mysql作为数据库管理系统,例如LAMP.和WAMP等,在针对网站渗透中,很 ...
- 一个扩展搜索API的优化过程
概述 API 是一个服务的门面,就像衣装是人的形象一样. 优雅的 API 设计,能让业务方使用起来倍儿爽,提升开发效率,降低维护成本:糟糕的 API 设计,则让业务方遭心,陷入混沌. 本文将展示一个扩 ...
- Yarn报错:Could not find any valid local directory for nmPrivate/
原因: yarn.nodemanager.local-dirs和hadoop的hadoop.tmp.dir参数对应文件位置不一致 解决办法: 将hdfs-site.xml中hadoop.tmp.dir ...
- 树莓派4B遇到的坑
由于大创需要用到机器学习这些东西,入手了一个树莓派4B(新手没弄过,直接上手最新版果然是有坑的),大佬勿喷
- css动画延迟好像有点怪
项目中需要使用到动画animate.css,在自定义的时候发现设置animation-delay 和 animation-duration 的总时间不对会导致 动画缺失. 比如 bounceInLef ...