还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,echarts等技术开发,欢迎加底部微信(gis-dajianshi),一起交流。
No. | 内容链接 |
---|---|
1 | Openlayers 【入门教程】 - 【源代码+示例300+】 |
2 | Leaflet 【入门教程】 - 【源代码+图文示例 150+】 |
3 | Cesium 【入门教程】 - 【源代码+图文示例200+】 |
4 | MapboxGL【入门教程】 - 【源代码+图文示例150+】 |
5 | 前端就业宝典 【面试题+详细答案 1000+】 |
文章目录
一、关键字二、应用场景三、示例代码四、注意事项:
async/await
是 JavaScript 异步编程的一种简化写法,它建立在 Promise 基础之上,提供了更加简洁和易于理解的方式来处理异步操作。以下是 async/await
的关键字、应用场景、示例代码以及注意事项。
一、关键字
async 关键字:
async
关键字用于声明一个函数为异步函数。异步函数总是返回一个 Promise,即使没有明确地返回一个 Promise,也会隐式地将其返回值包装在一个 resolved Promise 中。如果异步函数返回了一个非 Promise 值,它会被转换为 resolved Promise,返回值作为 resolve 的参数。 await 关键字:
await
关键字只能在 async
函数内部使用。await
后跟一个表达式,这个表达式的值通常是一个 Promise。当遇到 await
表达式时,JavaScript 会暂停异步函数的执行,等待 Promise 解决(resolved)或拒绝(rejected),然后恢复执行并返回 Promise 的结果或抛出错误。 二、应用场景
当需要串行处理多个异步操作时,async/await
可以帮助消除回调地狱(callback hell)和链式 .then()
方法带来的嵌套层次过深的问题。在 Node.js 中,用于处理文件 I/O、数据库查询、网络请求等异步操作,使得代码逻辑更加清晰、易于维护。 三、示例代码
// 异步获取数据的模拟函数function getDataFromApi(url) { return new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() > 0.5) { resolve(`Data from ${url}`); } else { reject(new Error('Failed to fetch data')); } }, 1000); // 模拟异步延迟 });}// 使用 async/await 的异步函数async function fetchDataSequentially(urls) { let results = []; for (const url of urls) { try { const data = await getDataFromApi(url); results.push(data); } catch (error) { console.error(`Error fetching data from ${url}:`, error); } } return results;}// 使用示例(async () => { const urls = ['api1', 'api2', 'api3']; try { const fetchedData = await fetchDataSequentially(urls); console.log(fetchedData); } catch (error) { console.error('An error occurred:', error); }})();
在上面的示例中,fetchDataSequentially
是一个异步函数,它逐个等待 getDataFromApi
的 Promise 完成,并将结果收集到数组 results
中。整个过程无需回调函数或 .then()
链式调用,代码如同同步执行般直观。注意,为了能够启动这个异步操作,我们在全局作用域使用了立即执行的 async 函数表达式 ((async () => {...})()
)。
四、注意事项:
使用 async/await
时,需要注意以下几点:
函数必须带有 async
关键字:
await
关键字,该函数必须被声明为 async
函数。否则会引发语法错误。 await
后接 Promise:
await
关键字后面通常跟着一个返回 Promise 的表达式。如果不是 Promise,它会被转换为已解决(resolved)的 Promise。如果 await
后的 Promise 被拒绝(rejected),那么 await
表达式将会抛出错误,需要用 try...catch
语句捕获。 同步外观下的异步行为:
尽管async/await
提供了类似于同步代码的写法,但实际上它仍然执行的是异步操作。这意味着 await
之后的代码并不会阻塞执行流,而是等待 Promise 解决后才会继续执行。因此,在某些情况下,需要特别注意代码执行的顺序,特别是涉及多个异步操作时,避免误认为所有操作会按顺序立即执行。 错误处理:
使用async/await
编写异步代码时,应该适当地使用 try...catch
结构来捕获和处理可能出现的错误。如果不这样做,Promise 的 rejection 将会导致异常冒泡至外层的 async
函数,并且如果没有被捕获,会导致整个脚本终止。 并发 vs. 串行:
在循环中使用await
时,代码默认会按照顺序逐个等待异步操作完成,即串行执行。如果需要并发执行多个异步任务,可以利用 Promise.all
或者 for...of
结合 await
实现。 资源管理:
在执行一系列异步操作时,尤其涉及数据库连接、文件流或者其他需要释放的资源,要注意及时关闭或释放资源,确保资源在使用完毕后得到妥善处理。避免阻塞:
尽管async/await
使得代码看上去像是同步的,但应当避免在长时间运行的操作前后不加区分地使用 await
,以免阻塞事件循环,影响应用的响应性。 内存占用和性能考量:
如果大量的异步操作堆积在一起,可能会增加内存消耗,因为每一个async
函数都会生成一个微型任务,加入到任务队列中。在高负载的情况下,需要合理设计异步流程以降低内存压力。 跨函数传播:
由于async
函数始终返回一个 Promise,因此在跨函数调用时,需确保下游函数也能正确处理 Promise,或者也将下游函数声明为 async
函数以便使用 await
。 兼容性和迁移成本:
虽然现代浏览器和 Node.js 已经全面支持async/await
,但在旧版本环境中可能需要 Babel 等转译工具来确保兼容性。在已有项目中引入 async/await
可能涉及到大量既有代码的重构。