常用的异步处理方式? 📅 2026/7/13 16:46:14 先给结论JavaScript 常见的异步处理方式主要有回调函数callbackPromiseGenerator yieldasync / await另外在具体场景里还有事件监听发布订阅定时器Promise 相关并发方法比如Promise.all、Promise.race如果是面试回答一般主线答这四个就够了回调函数 → Promise → Generator → async/await这也是 JavaScript 异步方案的演进路线。一、为什么需要异步因为 JS 是单线程的。如果遇到这些耗时操作都同步执行会阻塞主线程网络请求定时器文件读取用户交互等待数据库查询大量计算任务所以需要异步让任务先挂起等时机到了再回来执行。二、常见异步处理方式1. 回调函数Callback这是最早、最基础的异步处理方式。示例setTimeout(() { console.log(1秒后执行) }, 1000)或者function getData(callback) { setTimeout(() { callback(成功数据) }, 1000) } getData((res) { console.log(res) })优点简单直接兼容性好缺点容易形成回调地狱错误处理不统一可读性差逻辑嵌套深时难维护面试表达回调函数是最基础的异步方案核心是把后续逻辑作为函数传进去等异步任务完成后再调用。但多个异步串联时容易产生回调地狱。2. PromisePromise 是对回调函数的改进。示例const p new Promise((resolve, reject) { setTimeout(() { resolve(成功) }, 1000) }) p.then(res { console.log(res) }).catch(err { console.log(err) })优点链式调用更清晰状态明确pending / fulfilled / rejected错误处理更统一更适合多个异步流程组合缺点链太长时仍然不够直观写多了.then()也会影响可读性面试表达Promise 把异步操作封装成对象通过then/catch/finally处理结果相比回调函数更利于链式调用和统一错误处理。3. Generator yield这是 ES6 提供的一种“可暂停函数”能力也可以用于异步流程控制。示例function* gen() { const a yield Promise.resolve(1) const b yield Promise.resolve(2) return a b }但它本身不会自动执行需要执行器配合。优点可以把异步流程写得像同步流程函数可暂停、可恢复缺点使用成本高需要手动next()或额外执行器实际开发中现在基本被async/await取代面试表达Generator 通过yield暂停函数执行再由执行器恢复执行曾经用于异步流程控制但由于使用复杂后来更多被async/await替代。4. async / await这是当前最常用的异步处理方式。示例async function getData() { try { const res await Promise.resolve(成功) console.log(res) } catch (err) { console.log(err) } } getData()优点写法最接近同步代码可读性最好错误处理可以直接用try...catch适合复杂异步流程缺点本质上仍基于 Promise串行 await 写多了可能影响性能需要结合并发优化面试表达async/await 是目前最主流的异步方案本质上是 Promise 的语法糖让异步代码看起来像同步代码提升了可读性和维护性。三、除了这四种还常见哪些异步方式1. 定时器比如setTimeoutsetIntervalsetTimeout(() { console.log(异步执行) }, 0)它本质上也是异步任务的一种来源。2. 事件监听比如 DOM 事件button.addEventListener(click, () { console.log(点击了) })用户什么时候点击是不确定的所以本质上也是异步处理。3. 发布订阅 / EventBus通过事件机制处理异步通知。bus.on(done, (data) { console.log(data) }) bus.emit(done, 任务完成)这种常用于解耦异步流程。4. Promise 并发方法在实际开发中非常常用。Promise.all多个异步并发执行全部成功才返回。Promise.all([fetchA(), fetchB(), fetchC()]) .then(res console.log(res))Promise.race谁先完成就返回谁。Promise.race([fetchA(), fetchB()]) .then(res console.log(res))Promise.allSettled等所有 Promise 都结束不管成功失败。Promise.allSettled([p1, p2, p3]).then(res console.log(res))Promise.any只要有一个成功就返回。四、异步方案的演进过程这个很适合面试说。1. Callback最早的方案但嵌套多维护差。2. Promise解决回调地狱让异步流程更线性。3. Generator提供暂停恢复机制让异步控制更灵活。4. async/await在 Promise 基础上进一步简化写法成为主流。一句话概括JavaScript 异步处理方式经历了从回调函数到Promise再到Generator最终发展到async/await的过程。五、它们之间的区别1. 回调 vs Promise回调把后续逻辑传进去Promise把异步结果包装成对象统一管理状态和回调2. Promise vs async/awaitPromise通过.then()链式调用async/await通过同步写法处理异步更易读3. Generator vs async/awaitGenerator 的yield需要手动执行器恢复async/await 会自动等待 Promise 完成并恢复执行六、实际开发中怎么选这个回答会比较加分。1. 简单异步回调场景比如定时器、事件监听用回调就行。2. 多个异步串联优先用async/awaitasync function init() { const user await getUser() const order await getOrder(user.id) const detail await getDetail(order.id) return detail }3. 多个异步并发优先用 Promise 并发 APIconst [user, product, order] await Promise.all([ getUser(), getProduct(), getOrder() ])4. 需要事件驱动解耦可以用发布订阅 / EventBus。七、面试标准回答如果面试官问“常用的异步处理方式”你可以这样答JavaScript 常用的异步处理方式主要有回调函数、Promise、Generator 和 async/await。回调函数是最早的异步方案简单但容易形成回调地狱Promise 把异步结果对象化支持链式调用和统一错误处理Generator 通过yield实现函数暂停和恢复也能用于异步流程控制目前最常用的是 async/await它本质上是 Promise 的语法糖写法更接近同步代码可读性和维护性更好。此外在具体场景中还有事件监听、发布订阅、定时器以及Promise.all这类并发控制方式。八、30 秒短答版常见异步处理方式有回调函数、Promise、Generator 和 async/await。它们的发展路线是 callback → Promise → Generator → async/await。现在实际开发中最常用的是 Promise 和 async/await前者适合链式和并发控制后者更适合写复杂异步流程。九、一句话总结JS 异步处理方式的核心演进就是从“回调嵌套”走向“Promise 对象化”再到“async/await 同步化写法”。