es7异步 - async、await 让异步编程更简单
一、async await 概念
1. ECMAScript 2017 引入async函数,是generator 和 promises的语法糖,使异步代码更易于编写和阅读。通过使用它们,异步代码看起来更像是老式同步代码;
2. 不需要附加
.then()
代码块到每个promise-based方法的结尾,你只需要在方法调用前添加 await 关键字,然后把结果赋给变量。await 关键字使JavaScript运行时暂停于此行,允许其他代码在此期间执行,直到异步函数调用返回其结果。
3. 更少的.
then()
块来封装代码,同时它看起来很像同步代码,所以它非常直观。4. 想添加错误处理,可以将同步的
try...catch
结构和async/await
一起使用
二、async await 相关语法
async 函数
- 声明一个async函数,是使用
async
关键字,把它放在函数声明之前,使其成为 async function。异步函数也就意味着该函数的执行,不会阻塞后面代码的执行。- async函数 返回的是一个 promise 对象,而不是直接返回值。无论函数内是否有await操作
- 函数内部return返回的值,会成为then () 回调函数 的参数。
- 函数内部如果抛出错误,会被then的第二个参数 或者 catch捕获到。
// 语法
async function fn1() {//.....} let fn2 = async funtion(){ //.....} let fn3 = async ()=>{//.....}
将 async
关键字加到函数申明中,可以告诉它们返回的是 promise 对象,而不是直接返回值👇
async function testAsync() { return 111; } console.log(testAsync()); // 返回结果是一个promise对象,而不是 111 /*** * Promise * __proto__: Promise * [[PromiseStatus]]: "resolved" * [[PromiseValue]]: 111 * */ // async 封装的函数,正确调用方式: testAsync().then(res => { console.log(res); // 111 })
await关键字
- await 关键字不能单独使用, 只在异步函数里起作用。普通函数内会报错。(它可以放在任何异步的,基于 promise 的函数之前。它会暂停代码在该行上,直到 promise 完成,然后返回结果值。在暂停的同时,其他正在等待执行的代码就有机会执行了。)
- 正常情况下,await 后是一个Promise对象, 返回该对象结果; 如果await后不是Promise,就直接返回对应的值。
- await 是在等待后面表达式的执行结果。需要等待await后面的函数 运行完并且有了返回结果 之后,才继续执行下面的代码,同步的效果。
- 阻塞主函数的执行,直到后面的Promise函数返回结果
function testWait() { return new Promise((resolve,reject)=>{ setTimeout(function(){ console.log("testWait"); resolve(); }, 1000); }) } async function testAwaitUse(){ await testWait() console.log("hello"); return 123; // 输出顺序:testWait,hello // 不使用await输出顺序:hello , testWait } // testAwaitUse(); console.log(testAwaitUse())
示例:
async function myFetch() { let response = await fetch('coffee.jpg'); return await response.blob(); } myFetch()
.then((blob) => { let objectURL = URL.createObjectURL(blob); let image = document.createElement('img'); image.src = objectURL; document.body.appendChild(image); }) .catch((e) => console.log(e) );
三、Promise、generator、async
回忆Promise👇
改写为async写法👇
或以下写法👇
(二)、把 generator改造为 async方式
⚠️:不管加不加await, asycn函数返回的都是一个promise对象实例,值作为参数传递过去,then方法接收👇。
综上,推荐第一种 并行写法。
文档: MDN Web Docs