前言
ES2017 标准中引入了 async 函数,async 函数其实是 generator 的语法糖,相较于其他异步方法进行了用法上的改进,让 JS 的异步编程变得更加简单和优雅。
一、async & await 用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| async function getData() { console.log(1); const response = await fetch( "https://api.apiopen.top/getJoke?page=1&count=2&type=video", { mode: "cors", headers: { "Content-Type": "application/json" } } ); console.log(2); return response.json(); }
getData().then(res => { console.log(res); console.log(3); });
console.log(4);
|
async 函数总是会返回 Promise 对象,Promise.then() 回调方法的参数是 async 函数 return 的值。
async 函数在执行时会在 await 关键字语句挂起暂停执行,等待 await 右边的异步方法完成后再以 Promise.then() 的形式执行内部下面的语句,虽然会阻塞 await 下面的代码执行,但是并不会阻塞外部主线程方法的执行。
二、错误捕捉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| async function getData() { try { throw new Error("报错啦"); console.log(123456); return response; } catch (error) { console.log(error); } }
getData() .then(res => { console.log(res); }) .catch(err => { console.log(err); });
|
如果 async 函数中有 try catch,那么 async 函数将直接捕捉并处理到内部的错误, 不会继续执行后面的代码。而如果 async 函数中没有 try catch,那么错误会导致返回的 Promise 直接转移到 rejected 状态,进而在返回的 Promise.catch() 方法中捕捉到。
三、async & await 应用
我们再一次封装 ajax 方法~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| const Ajax = ({ method = "get", url = "/", data, async = true }) => { return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState === 4 && xhr.status === 200) { let res = JSON.parse(xhr.responseText); resolve(res); } }; xhr.open(method, url, async); if (method === "get") { xhr.send(); } if (method === "post") { let type = typeof data; let header; if (type === "string") { header = "application/x-www-form-urlencoded"; } else { header = "application/json"; data = JSON.stringify(data); } xhr.setRequestHeader("Content-type", header); xhr.send(data); } }); };
Ajax.get = url => { return Ajax({ url }); };
async function getData() { try { let data = await Ajax.get( "https://api.apiopen.top/getJoke?page=1&count=2&type=video" ); return data; } catch (error) { console.log(error); } }
getData().then(res => { console.log(res); });
|
总结
async&await 是结合 Promise 链式调用和 Generator 暂停执行的特点,且封装了 Generator 自执行函数,让代码看起来更像是同步执行,是未来异步编程的发展方向。