在前端开发中,经常会遇到需要异步处理的场景,例如异步请求数据或者调用接口等。Promise 是一种处理异步操作的非常优秀的机制。但是,使用 Promise 也有一些烦人的事情,比如回调地狱和错误处理。ES7 中引入了 async/await 关键字,可以大大改善 Promise 的使用体验。本文将介绍如何使用 ES7 中的 async/await 实现 Promise 链,帮助开发者更好地处理异步操作。
为什么需要 async/await
使用 Promise 的时候,我们通常会用 then 方法来处理异步回调逻辑。但是过多的 then 方法嵌套会导致代码难以理解和维护,形成了“回调地狱”的问题。而 async/await 可以有效避免这个问题。使用 async/await,可以将 Promise 形式的异步处理转化为同步代码的写法(类似于读取文件的 fs.readFileSync(),不过 async/await 可以不阻塞后续代码的执行),代码结构更加清晰简洁。
语法示例
下面是使用 async/await 实现 Promise 链的一个简单例子:
// javascriptcn.com 代码示例 function getData(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { resolve(xhr.responseText); } else if (xhr.readyState === 4 && xhr.status !== 200) { reject(new Error(xhr.responseText)); } }; xhr.send(); }); } async function getResult() { try { const data1 = await getData('https://example.com/api/data1'); console.log('data1:', data1); const data2 = await getData('https://example.com/api/data2'); console.log('data2:', data2); const data3 = await getData('https://example.com/api/data3'); console.log('data3:', data3); } catch(error) { console.error(error); } } getResult();
将异步请求函数 getData() 和 getResult() 中的 Promise 语句使用 async/await 关键字实现简化。在 getResult() 函数中,使用 try/catch 来处理异步回调过程中可能出现的错误。在执行时,所有的异步回调执行顺序会保证与代码顺序一致,而且代码也保持了同步式的简洁性。
深入了解 async/await
async/await 组合 Promise 模式可以非常高效地实现异步代码。如果能更深入地理解 async/await,就可以在前端项目中更好地应用它们。这里介绍一些注意点。
await 返回的值
使用 await 关键字,可以将 Promise 对象转化为同步式代码。但是,值得注意的是 await 关键字返回的值不是 Promise 对象,因此不可以在 await 后使用 then() 方法。举个例子,想获取 /api/data1 接口返回的数据,如果写成下列代码,是错误的:
async function getResult() { const data1 = await getData('https://example.com/api/data1') .then(response => response.json()); console.log(data1); }
正确的写法应该是:
async function getResult() { const response = await getData('https://example.com/api/data1'); const data1 = await response.json(); console.log(data1); }
错误处理
如果 async 函数内发生了异常,可以使用 try/catch 来捕获 throw error 语句抛出的错误。下列代码演示了一个错误处理示例:
// javascriptcn.com 代码示例 async function getResource() { try { const data1 = await getData('https://example.com/api/data1'); if (data1 && data1.code === '1000') { const data2 = await getData('https://example.com/api/data2'); if (data2) { console.log(data2); return; } } // 当出现数据异常,或者网络异常等原因时,抛出错误 throw new Error('get data error'); } catch(error) { console.error(error); } }
在上述代码中,当发生异常情况时,使用 throw new Error() 抛出错误,而不是直接使用 reject() 抛出异常。这样可以让 catch() 方法捕获到这个错误,从而更好地处理异常。
总结
现代前端开发越来越注重性能和用户体验方面的优化,这其中异步处理占据着非常重要的位置。而使用 ES7 中的 async/await ,可以极大的优化异步回调的代码质量和阅读体验。使用 async/await 需要注意特定的规则,例如使用 try/catch 捕获异常,异步回调顺序会与代码顺序一致等等。在合理使用这些规则的情况下,async/await 将会极大的优化代码的可读性和可维护性。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654f51037d4982a6eb8460ee