学过javascript的用户一定都知道javascript的功能特点,那就是异步调用,非阻塞IO。由于非阻塞IO的特性,决定了它可以支持高并发,但是一般的非阻塞IO,需要使用回调函数,如果回调深度过大,代码编写与维护难度就会大幅提升,最终掉入回调地狱。
为了解决这个问题,javascript es6提供了Promise的方案,在一定程度上缓解了这个问题,但是依旧写的会比较烦。
现在,我们就介绍另一种javascript解决异步调用的方法 --- async/await。
await:顾名思义,就是用来等待异步调用函数执行结束的语法糖,这个语法是基于Promise的,它的返回值是等待Promise的resolve。
例如一个函数被定义为返回Promise对象,这个函数就可以通过await进行等待。
function sleep (sec) { return new Promise (function (resolve, reject) { setTimeout (function () { resolve () }, 1000*sec) }) }
这个函数是一个典型的异步函数,以往的做法是使用
sleep(5).then(function () { // 延时5s console.log ('hello world') })
虽然我们可以使用Promise对象链,但是这方法依旧使用的是异步函数实现的,可读性上还是不行,但是如果使用下面方法,就会好很多。
await sleep(5) console.log ('hello world')
添加了await关键词,那么只要不执行resolve函数,await就会永远等待在这里,看上去就相当于同步方法。
await方法的返回值也是可以用于接收resolve的参数的。
如果想接收reject,就需要使用异常监听。
try { await sleep(5) } catch (e) { console.log (e) }
async:那么,如果await如此的好,直接使用不就行了。其实,事实上没有那么简单,由于await的方法通常是异步函数,必须在async函数中调用。也就是说async是声明“我里面包含异步”的。
因此如果我们想使用await sleep (5),就必须在声明了async的函数中使用。如:
async function main () { try { await sleep(5) } catch (e) { console.log (e) } console.log ('hello world') }
async/await混合调用:有时,如果一个函数要调用另一个async声明了的函数,并且希望按照同步的流程执行,对async声明了的函数,也需要使用await标记,才能保证同步执行。
function sleep (sec) { return new Promise (function (resolve, reject) { setTimeout (function () { resolve () }, 1000*sec) }) } async function callsleep () { try { await sleep(5) } catch (e) { console.log (e) } console.log ('hello world') } async function main () { await callsleep() await callsleep() await callsleep() }
文章作者:沃航科技