摘要:JavaScript 是单线程的(浏览器中主线程:渲染 + JS 共享一个线程)。如果所有任务都同步执行,遇到耗时操作(如 IO、网络请求、定时器)就会阻塞 UI,用户体验很差。所以需要异步机制,让长耗时任务交给宿主环境(浏览器 / Node.js),执行完再
好的 你问的是 JavaScript 异步解决方案以及实现原理,我给你整理一个比较系统的总结,包括常见方案、演进过程以及底层原理。
JavaScript 是 单线程 的(浏览器中主线程:渲染 + JS 共享一个线程)。
如果所有任务都同步执行,遇到耗时操作(如 IO、网络请求、定时器)就会 阻塞 UI,用户体验很差。
所以需要 异步机制,让长耗时任务交给宿主环境(浏览器 / Node.js),执行完再回调。
缺点:
回调地狱(Callback Hell):多层嵌套,可读性差。错误处理不统一(成功回调和失败回调分离)。ES6 引入,用于改进回调问题。核心思想:用一个对象表示未来的某个结果,有 pending → fulfilled / rejected 两种状态变化。new Promise((resolve, reject) => {setTimeout( => resolve('任务完成'), 1000);}).then(res => console.log(res)).catch(err => console.error(err));优点:
链式调用,解决回调地狱。统一错误处理(catch)。缺点:仍然有“回调”,只是形式更优雅。ES6 的 Generator 函数 可以配合 yield 暂停执行,让异步写法看起来像同步。需要配合 co 或手写执行器。function* task {const res = yield new Promise(r => setTimeout( => r('完成'), 1000));console.log(res);}co(task);
原理:
yield 暂停,co 执行器自动调用 next 并传入 Promise 的结果。async function run {try {const res = await new Promise(r => setTimeout( => r('完成'), 1000));console.log(res);} catch (err) {console.error(err);}}run;优点:
写法接近同步,逻辑清晰。错误处理可用 try...catch。缺点:需要注意并发执行时不要串行化(用 Promise.all)。const EventEmitter = require('events');const emitter = new EventEmitter;emitter.on('done', msg => console.log(msg));setTimeout( => emitter.emit('done', '任务完成'), 1000);
优点:适合多次触发的异步任务。
缺点:不适合链式依赖的异步流程。
JavaScript 自身是单线程的,异步的实现依赖 宿主环境(浏览器/Node.js):
JS 主线程执行同步任务。遇到异步任务(如 setTimeout、Promise、IO) → 交给宿主环境处理。宿主环境完成任务后,把回调推入 任务队列(Task Queue)。主线程空闲后,从队列取出任务执行 → 形成 事件循环(Event Loop)。宏任务 (Macro Task):script 整体执行、setTimeout、setInterval、IO、setImmediate(Node)。微任务 (Micro Task):Promise.then、MutationObserver、queueMicrotask。规则:每次执行完一个宏任务 → 清空所有微任务 → 再执行下一个宏任务。console.log('start');setTimeout( => console.log('宏任务'), 0);Promise.resolve.then( => console.log('微任务'));console.log('end');
输出顺序:
来源:小玉科技天地
免责声明:本站系转载,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本站联系,我们将在第一时间删除内容!