最近在学习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 重构一下代码。
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,返回根据第一个市里面的区县。
现在我们了解一下async/await的用法;
async关键字表示这个是一个异步函数,await只能使用在这个函数里面,如果是在普通函数就会报错;
await的作用是获取一个promise对象,获取返回值之前await后面的语句是无法继续执行的。假如await返回的不是一个promise对象,是其他的任何返回值,await后面的语句会立即执行。
ajax比较容易看出call hell问题,现在我们弄个简单的例子,可以在babel中执行一下。
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,就是
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。