对于js的async和await的理解分析
一、async和await
async和await的概念
1)async 函数是 Generator 函数的语法糖,使用 关键字 async 来表示,在函数内部使用 await 来表示异步
2)ES7 提出的async 函数,终于让 JavaScript 对于异步操作有了终极解决方案
3)async 作为一个关键字放到函数的前面,用于表示函数是一个异步函数,该函数的执行不会阻塞后面代码的执行
4)await是等待,只能放到async函数里面,在后面放一个返回promise对象的表达式
5)async和await是为了解决大量复杂不易读的Promise异步的问题
async函数的改进
1)内置执行器,Generator 函数的执行必须依靠执行器,而 Aysnc 函数自带执行器,调用方式跟普通函数的调用一样
2)更好的语义,async 和 await 相较于 * 和 yield 更加语义化
3)更广的适用性,co 模块约定,yield 命令后面只能是 Thunk 函数或 Promise对象,而 async 函数的 await 命令后面则可以是 Promise 或者 原始类型的值(Number,string,boolean,但这时等同于同步操作)
4)返回值是 Promise,async 函数返回值是 Promise 对象,比 Generator 函数返回的 Iterator 对象方便,可以直接使用 then() 方法进行调用
5)async方式,流程清晰,直观、语义明显,操作异步流程就如同操作同步流程, async 函数自带执行器,执行的时候无需手动加载。对于Promise的方式,如果处理流程复杂,整段代码将会充满then,不然很好的表示流程。对于Generator 方式,函数的执行需要依靠执行器,每次都需要通过 g.next() 的方式去执行
async和await的实例
1)async 作为一个关键字放到函数的前面,用于表示函数是一个异步函数,该函数的执行不会阻塞后面代码的执行
实例代码:
async function timeout(){return "hello word";}timeout();// Promise __proto__: Promise [[PromiseStatus]]: "resolved" [[PromiseValue]]: "hello word"//async返回的是 promise 对象console.log(timeout());// 我在后面,但是我是先执行的console.log("我在后面,但是我是先执行的");
2)async声明的函数的返回本质上是一个Promise,async函数内部会返回一个Promise对象,then方法回调函数的参数
实例代码:
// hello world11async function f1(){return "hello world11";};f1().then((v)=>console.log(v));
3)await的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖,用await声明的Promise异步返回,必须“等待”到有返回值的时候,代码才继续执行下去
实例代码:
/* hello1我是hello2输出 hello1*/const test = async()=>{let message = "hello1";let result = await message;console.log(result);console.log("我是hello2");return result;};test().then(result =>{console.log("输出",result);});
4)async 函数内部的实现原理是resolved,如果函数内部抛出错误, 则会导致返回的 Promise 对象状态变为 reject 状态,promise 对象有一个catch 方法进行捕获,被 catch 方法回调函数接收到
实例代码:
async function timeout2(flag){if(flag){return "hello world";}else{throw "failed";}}// 如果函数内部抛出错误, promise 对象有一个catch 方法进行捕获timeout2(false).catch(err => {console.log(err);});// hello word// 调用Promise.resolve() 返回promise 对象console.log(timeout2(true));// Uncaught (in promise) failed// 调用Promise.reject() 返回promise 对象console.log(timeout2(false));
5)async必须声明的是一个function,await就必须是在这个async声明的函数内部使用,必须是直系,作用域链不能隔代,在后面放一个返回promise对象的表达式
实例代码:
// 需求:2s后让数值乘以2function doubleAfter(num){return new Promise((resolve,reject)=>{setTimeout(()=>{resolve(2*num)},2000);});}// 60// 等待2s后,promis开始resolve,返回值async function test(){let result = await doubleAfter(30);console.log(result);}test();// 240//等待6s后,promis开始resolve,返回值async function test2(){let first = await doubleAfter(30);let second = await doubleAfter(40);let third = await doubleAfter(50);console.log(first+second+third);}test2();
6)函数的错误处理,当 async 函数中只要一个 await 出现 reject 状态,则后面的 await 都不会被执行,可以添加 try/catch
实例代码:
let a;async function f5(){await Promise.reject("error");a = await 1;}//f5().then(v=>console.log(a));// try/catch 解决// Uncaught (in promise) ReferenceError: error is not definedat f6 (test13.html:124)let a3;async function f6(){try{await Promise.reject("error");}catch{console.log(error);}a3 = await 123;return a3;}f6().then((v)=>console.log(a3));
async/await的实战
1)需求分析:有两个延时函数,先延时1秒,在延迟2秒,再延时1秒,最后输出“完成”
2)实例代码:
// 延时函数
const setDelay = (millisecond) => {return new Promise((resolve, reject)=>{if (typeof millisecond != 'number') reject(new Error('参数必须是number类型'));setTimeout(()=> {resolve(`我延迟了${millisecond}毫秒后输出的`)}, millisecond)})
}
const setDelaySecond = (seconds) => {return new Promise((resolve, reject)=>{if (typeof seconds != 'number' || seconds > 10) reject(new Error('参数必须是number类型,并且小于等于10'));setTimeout(()=> {resolve(`我延迟了${seconds}秒后输出的,注意单位是秒`)}, seconds * 1000)})
}/* 我延迟了${millisecond}毫秒后输出的我延迟了${seconds}秒后输出的,注意单位是秒我延迟了${millisecond}毫秒后输出的完成*/
(async ()=>{const result = await setDelay(1000);console.log(result);console.log(await setDelaySecond(2));console.log(await setDelay(1000));console.log('完成了');
})()
二、async和await的面试题总结
- 谈谈对 async/await 的理解,async/await 的实现原理是什么?
1)async/await 就是 Generator 的语法糖,使得异步操作变得更加方便
2)async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成await
3)async 是 Generator 的语法糖,这个糖体现在这几个方面:
- async函数内置执行器,函数调用之后,会自动执行,输出最后结果,而Generator需要调用next或者配合co模块使用
- 更好的语义,async和await,比起星号和yield,语义更清楚了,async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果
- 更广的适用性,co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async 函数的 await 命令后面,可以是 Promise 对象和原始类型的值
- 返回值是Promise,async函数的返回值是 Promise 对象,Generator的返回值是 Iterator,Promise 对象使用起来更加方便
4)async/await 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里
5)实例代码分析:
function my_co(it) {return new Promise((resolve, reject) => {function next(data) {try {var { value, done } = it.next(data);}catch(e){return reject(e);}if (!done) { //done为true,表示迭代完成//value 不一定是 Promise,可能是一个普通值。使用 Promise.resolve 进行包装。Promise.resolve(value).then(val => {next(val);}, reject);} else {resolve(value);}}next(); //执行一次next});
}
function* test() {yield new Promise((resolve, reject) => {setTimeout(resolve, 100);});yield new Promise((resolve, reject) => {// throw Error(1);resolve(10)});yield 10;return 1000;
}my_co(test()).then(data => {console.log(data); //输出1000
}).catch((err) => {console.log('err: ', err);
});
- 使用 async/await 需要注意什么?
1)await 命令后面的Promise对象,运行结果可能是 rejected,此时等同于 async 函数返回的 Promise 对象被reject。因此需要加上错误处理,可以给每个 await 后的 Promise 增加 catch 方法;也可以将 await 的代码放在 try…catch 中。
2)多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发
实例代码:
//下面两种写法都可以同时触发
//法一
async function f1() {await Promise.all([new Promise((resolve) => {setTimeout(resolve, 600);}),new Promise((resolve) => {setTimeout(resolve, 600);})])
}
//法二
async function f2() {let fn1 = new Promise((resolve) => {setTimeout(resolve, 800);});let fn2 = new Promise((resolve) => {setTimeout(resolve, 800);})await fn1;await fn2;
}
3)await命令只能用在async函数之中,如果用在普通函数,会报错
4)async 函数可以保留运行堆栈
实例代码:
/
* 函数a内部运行了一个异步任务b()。当b()运行的时候,函数a()不会中断,而是继续执行。
* 等到b()运行结束,可能a()早就* 运行结束了,b()所在的上下文环境已经消失了。
* 如果b()或c()报错,错误堆栈将不包括a()。
*/
function b() {return new Promise((resolve, reject) => {setTimeout(resolve, 200)});
}
function c() {throw Error(10);
}
const a = () => {b().then(() => c());
};
a();
/**
* 改成async函数
*/
const m = async () => {await b();c();
};
m();
对于js的async和await的理解分析相关推荐
- 简谈对ES7的async和await的理解
如果遇到过深度回调的朋友一定对JS的回调地狱再熟悉不过了,举个例子说(如果我的列子不恰当尽请谅解),常见的就是省市区级联吧,假如我要获取一个县级市的信息,那么我首先得获得它所在的省的信息,当取得省的信 ...
- java有async和await吗,理解 JavaScript 的 async/await
2020-06-04 更新 JavaScript 中的 async/await 是 AsyncFunction 特性 中的关键字.目前为止,除了 IE 之外,常用浏览器和 Node (v7.6+) 都 ...
- async和await理解代码
<1>:Async和Await的理解1 using System; using System.Collections.Generic; using System.Linq; using S ...
- async 和 await 之异步编程的学习
async修改一个方法,表示其为异步方法.而await表示等待一个异步任务的执行.js方面,在es7中开始得以支持:而.net在c#5.0开始支持.本文章将分别简单介绍他们在js和.net中的基本用法 ...
- async And await异步编程活用基础
async And await异步编程活用基础 原文:async And await异步编程活用基础 好久没写博客了,时隔5个月,奉上一篇精心准备的文章,希望大家能有所收获,对async 和 awai ...
- Promise async/await的理解和用法
Promise && async/await的理解和用法 为什么需要promise(承诺)这个东西 在之前我们处理异步函数都是用回调这个方法,回调嵌套的时候会发现 阅读性 和 调试 的 ...
- Node.js「二」—— fs 模块 / async 与 await
本文为 Node.js 系列笔记第二篇.文章参考:nodejs 教程 -- 大地:<深入浅出 Node.js>:阮一峰 nodejs 博客: 添加链接描述 文章目录 一.fs 模块常用读写 ...
- nodejs async await promise理解
这篇文章是让大家更好理解 nodejs的async 和await 以及promise, 其实await状态虽然是在你需要的步骤里面是同步的,但是整个系统状态是异步的,是异步里面的同步,无需担心系统性能 ...
- 小程序高级电商前端第2周深入理解REST API开发规范 开启三端分离编程之旅<二>----scroll-view组件的灵活应用、async和await问题探讨、spu-scroll自定义组件
前言: 转眼距离上一次写博文又过去一个月了,今年的博文节奏已经彻底被打破了: 真的是有心无力了,其原因在之前也提到过,组织架构调整,各种考核(跨领域性质的考核)实行末尾淘汰制,说不出的酸楚,不过换个心 ...
最新文章
- 编译microwindow(nano-X) 及flnx-0.18
- Android之基于AssetManager实现换肤方案
- ActiveMQ 事务消息 手工签收
- JavaScript入门第一天,js教程,js变量, 数据类型,数据转换,隐式转换
- Exploiting “BadIRET” vulnerability (CVE-2014-9322, Linux kernel privilege escalation)
- CSS实现div悬浮框的代码(兼容IE6)
- 移动端手指操控左右滑动的菜单
- python3怎么安装gmpy2_python2/3 模块gmpy2在linux下安装
- linux 文件系统cache,终于找到一篇详解Linux文件系统Cache的文章
- php 三个点 三角形面积,知道三角形三个顶点坐标,求面积,我觉得我的没错,但未通过,麻烦大佬帮忙看下...
- android 480p分辨率,[RK3399][Android7.1] HDMI显示屏(副屏)调试记录小结
- php获取当前页面select的值,关于JS获取select的值
- 制作windows7系统的U盘启动盘
- 数学建模2-美国人口增长模型的确定
- 魅族 android 文件传输,魅族文件管理app提取下载
- 步进电机驱动技术3:基于ULN2003的步进电机驱动
- Matlab下的整数规划(CVX)
- 规则引擎解决方案浅析
- 初探微信小游戏(一)
- Android正方形View
热门文章
- 5种主流浏览器的内核
- 微信最烧脑游戏计算机2sin,微信史上最烧脑游戏答案大全_史上最烧脑游戏攻略汇总_快吧小程序...
- Python爬取王者荣耀英雄图片及装备
- 网络爬虫笔记—滑动验证码识别
- 钢笔墨水能否代替打印机墨水_日本兔村文具店的原创文具钢笔墨水温柔如诗的美好设计...
- 广东工业大学文远知行杯新生程序设计竞赛(牛客比赛)
- ISCC 2019 杂项 倒立屋 (房屋为什么会倒立!是重力反转了吗?)
- php dhcp,dhcp是什么意思
- Java实战之管家婆记账系统(6)——导入和导出功能实现
- 微信小程序商城系统源码