基于 JS 事件循环的异步编程,走向大道至简
2023-11-01 18:35:03
揭秘 JS 的异步之道
一、单线程的局限
众所周知,JavaScript 是一门单线程语言,这意味着它一次只能执行一个任务。这个特性有其优势,它可以避免多线程编程中出现的竞争条件和死锁等问题,但同时也限制了它的并发性。如果一个任务执行时间过长,那么其他任务就只能等待,导致整个程序卡顿。
二、事件循环的奥秘
为了解决单线程的局限,JavaScript 引入了事件循环(Event Loop)的概念。事件循环是一个不断运行的循环,它负责在主线程空闲时执行异步任务。当一个异步任务完成时,事件循环会将它放入一个队列中,等待主线程空闲时执行。
事件循环的运行过程大致如下:
- 主线程执行同步任务。
- 主线程遇到异步任务时,将其放入异步任务队列。
- 主线程继续执行同步任务,直到遇到下一个异步任务。
- 主线程空闲时,从异步任务队列中取出任务并执行。
- 重复步骤 2-4,直到所有任务都执行完毕。
三、异步编程的利器
JavaScript 中的异步编程主要依靠三种技术:回调函数、Promise 和 async/await。
1. 回调函数
回调函数是 JavaScript 中最常用的异步编程技术。回调函数是一个函数,它在异步任务完成后被调用。回调函数的典型用法如下:
function doSomethingAsync(callback) {
setTimeout(() => {
// 异步任务完成后,调用回调函数
callback();
}, 1000);
}
doSomethingAsync(function() {
console.log("异步任务已完成!");
});
2. Promise
Promise 是 JavaScript 中的另一种异步编程技术。Promise 对象表示一个异步操作的结果,它有三种状态:pending(等待)、fulfilled(已完成)和 rejected(已拒绝)。Promise 的典型用法如下:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
// 异步任务完成后,调用 resolve 或 reject
resolve("异步任务已完成!");
}, 1000);
});
promise.then(result => {
console.log(result);
});
3. async/await
async/await 是 JavaScript 中最新引入的异步编程技术。它允许我们在代码中使用同步的写法来处理异步任务。async/await 的典型用法如下:
async function doSomethingAsync() {
const result = await new Promise((resolve, reject) => {
setTimeout(() => {
// 异步任务完成后,调用 resolve 或 reject
resolve("异步任务已完成!");
}, 1000);
});
console.log(result);
}
doSomethingAsync();
结语
JavaScript 的事件循环是其异步编程的基础,它使得 JavaScript 可以在单线程的环境中实现并发的效果。回调函数、Promise 和 async/await 是 JavaScript 中的三种主要异步编程技术,它们各有其优缺点,开发者可以根据不同的场景选择合适的技术。