es7中的async、await使用方法示例详解
人气:0async、await 是es7里面的新语法,它的作用就是 async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。它可以很好的替代promise 中的then。async 函数返回一个 Promise 对象,可以使用then 方法添加回调函数。当函数执行的时候,一旦遇到await 就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
一、前言
回调是JavaScript在es5之前处理异步方法的常用方式,当异步调用又调用了异步方法时,前端的小伙伴们应该都遇到过这种场景吧,回调方式的写法让人看得头皮发麻,代码的可读性非常差
ES2015中引入Promise, 目的就是为了解决著名的回调地狱,但是它自己引入了语法复杂性。示例如下:
function takeLongTime() { return new Promise(resolve => { setTimeout(() => resolve("long_time_value"), 1000); }); } takeLongTime().then(v => { console.log("got", v); });
ES2017增加了异步函数async/await,提高了代码可读性,让调用异步方法像同步一样简单。示例如下:
function takeLongTime() { return new Promise(resolve => { setTimeout(() => resolve("long_time_value"), 1000); }); } async function test() { const v = await takeLongTime(); console.log(v); } test();
async/await使代码看起来像是同步的,但它在后台是异步和非阻塞的。可以理解 await 后面的语句相当于放到了 new Promise 中,下一行及之后的语句相当于放在 Promise.then 中。 async 会将其后的函数(函数表达式或 Lambda)的返回值封装成一个 Promise 对象,而 await 会等待这个 Promise 完成,并将其 resolve 的结果返回出来。
二、async 和 await 的基础使用
async/awiat 的使用规则:
async 返回的是一个 Promise 成功的对象,await 就是等待这个 promise 的返回结果后,再继续执行
await 等待的是一个 Promise 对象,后面必须跟一个 Promise 对象,但是不必写 then (),直接就可以得到返回值
但注意,await 所等待的 promise 对象,他的最终状态一定是 resolve 的(当然也可以不是 resolve ,只不过不会执行后面的代码罢了),否则不会执行await 后面的代码,也就是不会去执行所谓的 then() ;
三、async \ await使用场景
//将请求改造成一个通用函数 function request(options) { //..... return new Promise(....); //使用Promise执行请求,并返回Promise对象 } //于是我们就可以来发送请求了 request("ajaxA") .then((data)=>{ //处理data return request("ajaxB") }) .then((data)=>{ //处理data return request("ajaxC") }) .then((data)=>{ //处理data return request("ajaxD") })
如果能像使用同步代码那样, 使用Promise就好了。于是, async \ await出现了
function request(options) { //..... return new Promise(....); //使用Promise执行请求,并返回Promise对象 } //wait这个单词是等待的意思 async function load(){ await request("ajaxA"); //那么这里就是在等待ajaxA请求的完成 await request("ajaxB"); await request("ajaxC"); await request("ajaxD"); }
await关键字使用的要求非常简单, 后面调用的函数要返回一个Promise对象。load()这个函数已经不再是普通函数, 它出现了await这样"阻塞式"的操作 因此async关键字在这是不能省略的。与之前长长的then链和then方法里的回调函数相比,这样的写法看起来像是同步写法并且更加清爽,更加符合编程习惯。
四、await返回打印测试
await后面的promise状态不是resolve的输出结果
async function async1 () { console.log('async1 start'); await new Promise(resolve => { console.log('promise1'); }) console.log('async1 success'); return 'async1 end' } console.log('srcipt start') async1().then(res => console.log(res)) console.log('srcipt end') /* await后面的promise状态不是resolve的输出结果 "srcipt start" "async1 start" "promise1" "srcipt end" */
这里我们可以看到:在 async1 中 await 后面的 Promise 是没有返回值的,也就是它的状态始终是 pending 状态,所以在 await 之后的内容是不会执行的,包括 async1 后面的 .then。
await后面的promise状态是resolve的输出结果
async function async1 () { console.log('async1 start'); await new Promise(resolve => { console.log('promise1'); resolve() }) console.log('async1 success'); return 'async1 end' } console.log('srcipt start') async1().then(res => console.log(res)) console.log('srcipt end') /*await后面的promise状态是resolve的输出结果 "srcipt start" "async1 start" "promise1" "srcipt end" "async1 success" "async1 end" */
五、总结
解决函数回调经历了几个阶段, Promise 对象, Generator 函数到async函数。async函数目前是解决函数回调的最佳方案。很多语言目前都实现了async,包括Python ,java spring,go等。
async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
加载全部内容