前端项目中常用es6知识总结 -- Async、Await让异步美如画
项目开发中一些常用的es6知识,主要是为以后分享小程序开发、node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫。
项目开发常用es6介绍
-
1、块级作用域 let const
-
2、箭头函数及this指向
-
3、promise、asnyc await语法
-
4、模块化 module export和import
-
5、解构赋值、字符串模板
-
……
asnyc await
首先看一段代码示例:
var promise = () => new Promise((resolve, reject) => { setTimeout(() => { resolve("我是数据") }, 1000) }) var func = async () => { var data = await promise(); //await用于等待promise函数的结果 console.log(data) return data // 一秒后打印出 “我是数据” } console.log(func()) // Promise {<pending>} 即func函数的返回值是一个Promise //调用就立即返回一个状态为pending的Promise,一秒后变成resolve状态
由此可以看出:
1、async表示函数里有异步操作
2、await表示紧跟在后面的表达式需要等待结果(阻塞代码往下执行)
3、async函数的返回值是 Promise 对象
既然async函数的返回值是 Promise 对象,那就可以使用then方法来接收resolve传递过来的参数,上述代码也可以这样实现:
var promise = () => new Promise((resolve, reject) => { setTimeout(() => { resolve("我是数据") }, 1000) }) var func = async () => { var data = await promise(); //await用于等待promise函数的结果 console.log(data) return data // 一秒后打印出 “我是数据” } // console.log(func()) // Promise {<pending>} 即func函数的返回值是一个Promise //调用就立即返回一个状态为pending的Promise,一秒后变成resolve状态 func().then((data) => { console.log(data) //我是数据 })
所以,再追加一条:
4、async函数内部return语句的返回值,就是then方法回调函数的参数。
也就意味着如果async函数内部没有写return语句,then方法回调函数的参数值就是undefiend。
错误处理
如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject。同样如果有多个await,其中一个出错也会将Promise 对象的状态置为reject。所以在进行错误处理的时候所以最好把await命令放在try…catch代码块中。
var promise = (data, ms) => new Promise((resolve, reject) => { setTimeout(() => { resolve(data) }, ms) }) var func = async () => { try { var data1 = await promise("数据1", 1000); console.log(data1) var data2 = await promise("数据2", 1000); console.log(data2) var data3 = await promise("数据3", 1000); console.log(data3) } catch (error) { console.error(err) } } func() //每隔一秒依次打印 数据1 数据2 数据3 //如果希望当前一个异步失败不影响后面的异步操作执行可以将其单独放在try{}catch(){}语句里
注意:多个await命令后面的异步操作,如果不存在相互依赖关系,最好让它们同时触发。因为当多个await后面的异步操作是一个接一个的完成的,这样会比较耗时,如果将他们同时触发则会大大缩短程序执行的时间。比如上述代码可以按照如下写法同时执行:
var promise = (data, ms) => new Promise((resolve, reject) => { setTimeout(() => { resolve(data) }, ms) }) var func = async () => { try { //写法1 var data = await Promise.all([promise("数据1", 1000), promise("数据2", 1000), promise("数据3", 1000)]); console.log(data) //["数据1", "数据2", "数据3"] //写法2 var datafn1 = promise("数据1", 1000); var datafn2 = promise("数据2", 1000); var datafn3 = promise("数据3", 1000); var data1 = await datafn1; var data2 = await datafn2; var data3 = await datafn3; console.log(data1, data2, data3) //数据1 数据2 数据3 } catch (error) { console.error(error) } } func()
上面两种写法,都是同时触发,这样就会缩短程序的执行时间。 注意:正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。
async function func() { // return 123; // return await 123; return await Promise.resolve(123) } func().then(function(data) { console.log(data) //123 })
当然:如果func函数内部没有写return,then方法的回调函数里data就等于undefined