最近在学习NodeJS框架koa V2,koa2的API很简单,基于ES7 async/await实现异步代码。不少人认为async/await是解决异步终极解决方案,那咱们就研究下async/await。
前端业务逻辑愈来愈复杂,每每几个 AJAX 请求之间互有依赖,有些请求依赖前面请求的数据,有些请求须要并行进行。咱们用ajax来作个例子,根据查找一个省份中的第一个市的区县。前端
$.get('/url/city',[province:'河北省'],function (result1){ console.log(result1); $.get('/url/county',[city:result1[1]],function (result2){ console.log(result2); }) })
这个是用回调函数执行的异步操做,大量的异步操做就有大量的回调函数,如今咱们是嵌套来三层,假如咱们嵌套了四层五层更多层,这个时候使用回调函数来写代码每每会致使代码难以阅读,就会造成了回调地狱Callback hell。
如今咱们用比较优雅一点的,看起来像同步实则异步的async/await 重构一下代码。ajax
var requestUrl=(url,args)=>{ return new Promise(function(resolve,reject){ $.get(url,args,(result)=> { try { resolve(JSON.parse(result)); }catch(e){ reject(e); } }) }) } async function getCounty(province){ try{ let result1=await requestUrl('/url/city',{provinces:province}); console.log(result1); }catch(e){ console.log(e); } try{ let result2=await requestUrl('/url/county',{city:result1[1]}); console.log(result2); }catch(e){ console.log(e); } }; getCounty('河北省');
首先咱们定义了一个requestUrl函数,这个函数返回一个Promise对象resolve,并拿到结果,当即执行函数定义时使用了关键字async,在函数体中配合使用了await,执行第一个await会返回‘/url/province’的执行数据全部河北省的市,执行第二个await,返回根据第一个市里面的区县。promise
如今咱们了解一下async/await的用法;babel
async关键字表示这个是一个异步函数,await只能使用在这个函数里面,若是是在普通函数就会报错;
await的做用是获取一个promise对象,获取返回值以前await后面的语句是没法继续执行的。假如await返回的不是一个promise对象,是其余的任何返回值,await后面的语句会当即执行。框架
ajax比较容易看出call hell问题,如今咱们弄个简单的例子,能够在babel中执行一下。koa
var sleep = function (time) { setTimeout(function () { console.log('test'); }, time); }; var start = async function () { console.log('start'); await sleep(3000); console.log('end'); };
start();
这个是没有返回promise对象的例子,执行start()后,先输出’start‘,而后'end',三秒钟后输出'test';异步
var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve('test'); console.log('test'); }, time); }) }; async function start() { console.log('start'); let result = await sleep(8000); console.log('end'); }; start(); 这个是返回promise对象,它先输出‘start’,而后是等待三秒输出‘test’,最后输出‘end’;
在学习过程当中,我被一句话给误导了,‘看起来像同步实则异步的async/await’,就走到了一个死胡同里,await关键字声明一个异步函数,可是await阻止了await后面语句执行,只有await等到了一个返回值才会继续执行,这不就是同步执行了吗?完全的懵了,后来恍然大悟,async声明start()为异步函数,假如再有一个start2(),它们并行执行的,在babel里面测试以下图:
因此异步的点在这。而await关键字只有获得返回值后才继续执行,不就是同步么。搞定!!!
async函数返回一个Promise对象,可使用then()添加回调,catch()捕获异常,当咱们也能够用try/catch,就是async