JS 异步编程
约 1075 字大约 4 分钟
2025-03-12
优点
提高性能:当执行某个操作时,异步编程可以让程序在等待结果的同时继续执行其他任务,从而最大限度地利用计算资源。这样可以提高程序的整体性能,特别是在涉及到大量计算或 I/O 操作的情况下。
增强用户体验:通过异步编程,可以将那些可能会阻塞用户界面的操作移到后台执行,从而保持用户界面的响应性。例如,在网页应用程序中,异步编程能够防止页面冻结,让用户能够继续进行其他操作。
简化代码逻辑:异步编程使得处理复杂的并发逻辑变得更加简单。相比于使用线性的同步代码,异步编程可以使用回调、Promise、async/await 等机制来组织代码,使得逻辑更加清晰和易于维护。
支持并发操作:异步编程提供了一种方式来同时执行多个任务。通过并发执行,可以加快任务的完成速度,从而提高整体效率。
一、回调函数 CallBack
在异步操作完成后,通过回调函数来处理结果或执行下一步操作。这是 JavaScript 中最早也是最基本的处理异步的方式,但会导致回调地狱问题。
function fetchData(callback) {
setTimeout(() => {
const data = "Hello, world!";
callback(null, data);
}, 1000);
}
fetchData((error, data) => {
if (error) {
console.error("Error:", error);
} else {
console.log("Data:", data);
}
});
二、Promise
Promise
是 JavaScript 中处理异步编程的一种机制,可以通过链式调用的方式来处理多个异步操作,提供了更好的错误处理和代码组织的能力。它是 ES6 引入的一个对象,用于表示一个异步操作的最终完成或失败,并返回相应的结果或错误。让我们以 链式调用 的方式去处理异步操作。
可以通过引用第三方库bluebird
和rxjs
、回调函数中引用外部变量来取消Promise
Promise 的基本概念是有三个状态:
- 已决议(resolved):表示操作已成功完成,并返回相应的结果
- 已拒绝(rejected):示操作失败,并返回相应的错误。
- 等待中(pending):操作还没结束,还在等待
当一个异步操作完成时,Promise 可以改变状态为已决议或已拒绝。
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = "Hello, world!";
resolve(data);
}, 1000);
});
}
fetchData()
.then((data) => {
console.log("Data:", data);
})
.catch((error) => {
console.error("Error:", error);
});
三、async/await
async/await
是 ES8 引入的一种更简洁、可读性更强的处理异步操作的方式。它是基于 Promise 的一种更简洁的异步编程语法。使用 async
关键字标记一个函数为异步函数,使用 await
关键字来等待 Promise
执行结果。
async/await
让异步代码看起来像同步风格,使得处理异步操作变得更简洁和易读。相比于使用回调函数或 Promise 的 then() 方法链,使用 async/await
可以更直观地表达异步操作的逻辑。
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = "Hello, world!";
resolve(data);
}, 1000);
});
}
async function fetchDataAsync() {
try {
const data = await fetchData();
console.log("Data:", data);
} catch (error) {
console.error("Error:", error);
}
}
fetchDataAsync();
四、Promise 和 async/await 有什么区别
区别 | async/await | Promise |
---|---|---|
语法 | 使用 async 关键字声明异步函数,在函数内使用 await 关键字等待 Promise 对象的执行结果 | 使用 new Promise() 创建一个 Promise 对象,并使用 then 和 catch 方法来处理结果 |
错误处理 | 使用 try/catch 块来捕获和处理错误 | 使用 catch 方法来处理错误 |
可读性 | 代码更接近同步代码,易于理解和维护 | 代码较为冗长,使用了回调和链式调用 |
并发操作 | 可以使用 await Promise.all([...]) 来并行执行多个 Promise 对象 | 通过链式调用来实现串行或并行的操作 |
嵌套调用 | 使用嵌套的 try/catch 和多层的 await 来处理多个异步操作 | 使用链式调用和嵌套的 then 方法来处理多个异步操作 |
异常堆栈跟踪 | 提供更好的异步堆栈跟踪能力 | 异步堆栈跟踪相对较弱 |
更新日志
e7112
-1于