ES6 中的异步函数 async/await
是一种简化异步操作的新型语法,可以在不破坏代码可读性和维护性的基础上解决回调函数和 Promise 的问题,同时提高代码执行效率和错误处理能力。本文将介绍 async/await
的基本概念、语法特点、使用场景及常见误区,并提供实例代码以供学习和参考。
一、什么是异步函数 async/await?
异步函数 async/await
是 ECMAScript 2017
标准新增的特性,它是基于 Promise 的规范进行的一层封装,可以更加直观和简洁地表达异步操作,减少了回调函数和 Promise 的嵌套和书写量,同时保持了异步操作的顺序和可读性。在语法层面上,使用 async
命令声明异步函数,函数内使用 await
命令等待 Promise 对象的状态变化,从而获取相应的结果。
async function asyncFunc(){ let result = await promise; return result; }
异步函数 async/await
将异步操作转化为同步操作的语法,使得代码具有更加优雅和自然的形式。但同时也需要注意其使用的限制和误区,例如 await
命令仅能在异步函数内部使用,且异步函数内部仅能包含一个 await
命令等等。
二、异步函数 async/await 的语法特点
异步函数 async/await
作为 Promise
的语法糖,它的特点主要集中在以下几个方面:
1、异步函数使用 async 命令声明
异步函数 async/await
的语法基于 async
命令进行声明,这样可以明确地表明函数的异步性质,并且函数的返回值也会被自动封装为 Promise 对象。
async function asyncFunction() { // ... }
2、异步函数内部使用 await 命令等待 Promise 对象的状态变化
异步函数 async/await
内部使用 await
命令等待 Promise 对象的状态变化,当 Promise 对象状态变为 resolved
或 rejected
时,await
命令将返回 Promise 对象的结果或错误信息。
async function getRequest(){ try { const response = await fetch(url); const data = await response.json(); console.log(data); } catch (error) { console.log(error); } }
3、异步函数返回的结果为 Promise 对象
异步函数 async/await
的返回值也会被自动封装为 Promise 对象,可以使用 then()
方法和 catch()
方法对异步操作进行相应的处理。
async function asyncFunc() { let result = await promise; return result; } asyncFunc().then(result => console.log(result)).catch(error => console.log(error));
4、异步函数内部不能使用 yield 命令
在异步函数 async/await
中,不能使用 yield
命令,在此处使用 yield
命令将会报错。
async function asyncFunc() { yield value; // SyntaxError: Unexpected identifier }
5、异步函数内部不能使用箭头函数
异步函数 async/await
内部不能使用箭头函数,因为这会改变 this
的指向,导致上下文环境的错误。
async function asyncFunc() { somePromise.then((result) => { // Uncaught TypeError: Cannot read property 'bind' of undefined // ... }); }
三、异步函数 async/await 的使用场景
异步函数 async/await
是一种优雅和简洁的语法,可以应用于各种异步操作场景,包括网络请求、定时器、事件监听等等。在 async/await
中,可以使用 try...catch
语句捕获异步操作中的错误,并且可以使用 Promise.all()
方法实现多个异步操作的同时进行。
async function asyncFunc() { try { const result1 = await somePromise1(); const result2 = await somePromise2(); const result3 = await somePromise3(); return [result1, result2, result3]; } catch (error) { console.log(error); } } asyncFunc().then(result => console.log(result)).catch(error => console.log(error)); // 多个异步操作同时进行 Promise.all([somePromise1(), somePromise2(), somePromise3()]).then(values => console.log(values));
四、异步函数 async/await 的常见误区
异步函数 async/await
是一种简洁和直观的语法,但是在应用时也存在一些常见的误区,需要特别注意和避免。
1、异步函数不能在 foreach 循环中使用
在异步函数 async/await
中不能在 foreach 循环中使用,这会导致等待 Promise 状态变换的结果混淆和错误。
async function asyncFunc(items) { await items.forEach(async (item, index) => { // 不应该在 foreach 循环中使用 await 命令 const result = await someAsyncFunc(item); console.log(index, result); }); }
2、异步函数不能使用 async/await 内部再次嵌套
在异步函数 async/await
中不能套用 async/await,这会出现 Promise 的链式调用问题,从而导致性能和代码逻辑混乱。
async function asyncFunc() { await somePromise.then(async (result1) => { const result2 = await someAsyncFunc(result1); console.log(result2); }); }
3、异步函数使用 await 命令时需要注意 Promise 的 reject 处理
在异步函数 async/await
中使用 await
命令时,需要注意 Promise 对象的 reject
处理,否则会出现 TypeError 类型错误。
async function asyncFunc() { try { const result1 = await somePromise1(); const result2 = await somePromise2(); const result3 = await somePromise3(); return [result1, result2, result3]; } catch (error) { console.log(error.message); } } asyncFunc().then(result => console.log(result)).catch(error => console.log(error.message));
五、异步函数 async/await 的示例代码
1、异步函数进行网络请求
async function getRequest(){ try { const response = await fetch(url); const data = await response.json(); console.log(data); } catch (error) { console.log(error); } }
2、异步函数进行事件监听
async function listenEvent() { return new Promise(resolve => { eventEmitter.on('event', data => { console.log(data); resolve(data); }); }); } listenEvent().then(result => console.log(result)).catch(error => console.log(error));
3、异步函数进行定时器操作
async function delay(time) { return new Promise(resolve => setTimeout(resolve, time)); } async function repeatFunc(func, time, repeatCount) { let count = 0; while (count < repeatCount) { await delay(time); func(); count++; } } repeatFunc(() => console.log('repeat'), 1000, 5);
六、总结
异步函数 async/await
是一种优雅和简洁的异步操作语法,可以有效地简化 Promise 和回调函数的代码量,同时还保持了异步操作的可读性和可维护性。在使用 async/await
时需要特别注意其限制和误区,并在实际应用中充分发挥其特点和优势,提高代码执行效率和错误处理能力。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a2b03dadd4f0e0ffac9e39