如何明白 JS 的异步?

打印 上一主题 下一主题

主题 595|帖子 595|积分 1785

1. JavaScript 是单线程的

JavaScript 作为一门语言,本身只在一个线程中运行,即 主线程,它一次只能实行一个使命。无论是操作 DOM,照旧实行计算密集型代码,JavaScript 都是在这个单独的主线程中完成的。单线程的计划初衷是为了简化开发,避免复杂的并发题目(如死锁、竞态条件等)。
2. 浏览器情况支持多线程

固然 JavaScript 是单线程的,但浏览器本身是多线程的,除了 JavaScript 线程,浏览器还提供了多个 辅助线程 来处置惩罚其他使命,比如:


  • 渲染线程:负责绘制页面内容。
  • 定时器线程:处置惩罚 setTimeout 和 setInterval。
  • 网络线程:处置惩罚网络哀求(如 AJAX、fetch 等)。
  • 变乱处置惩罚线程:处置惩罚用户输入、鼠标点击等变乱。
JavaScript 主线程并不会直接与这些线程交互,而是通过异步回调的方式等待其他线程完成工作,再在主线程中处置惩罚结果。
3. JavaScript 的异步机制:使命交给其他线程

当你在 JavaScript 中调用 setTimeout、fetch 或者实行变乱监听时,JavaScript 主线程并不会现实行止置惩罚这些耗时操作,而是将使命交给浏览器中的相应线程处置惩罚。


  • 例子 1:当你使用 setTimeout 时,定时器并不会阻塞 JavaScript 主线程,而是由浏览器的 定时器线程 来计时。当时间到了,定时器线程会将回调函数推送到 使命队列 中,等待主线程空闲时再实行。
  • 例子 2:当你发起一个网络哀求(如 fetch),这个哀求会交给浏览器的 网络线程 处置惩罚。当数据返回时,网络线程会将回调函数放入使命队列,等待主线程来处置惩罚返回的数据。
4. 变乱循环和使命队列

JavaScript 的 变乱循环(Event Loop) 负责调度这些异步使命。简单来说,变乱循环就是不停检查主线程是否空闲,如果空闲,就从 使命队列 中取出使命来实行,这就是为什么异步代码不会阻塞主线程的原因。
具体流程如下:

  • 主线程实行同步代码。
  • 当遇到异步使命(如 setTimeout、fetch),它们被交给其他线程处置惩罚。
  • 其他线程完成使命后,将回调函数放入使命队列。
  • 主线程实行完同步使命后,变乱循环会检查使命队列并实行回调函数。
5. 浏览器是多线程的,JS 保持单线程

固然浏览器有多个线程负责不同的使命,但这些辅助线程并不会与 JavaScript 主线程并行实利用命。它们只是辅助 JavaScript 主线程处置惩罚异步操作的结果,JavaScript 仍旧保持单线程的实行方式。
因此,JavaScript 本身仍旧是单线程的,但它依赖浏览器提供的多线程本领实现异步行为。
总结



  • JavaScript 是单线程的,所有代码都在一个线程中实行,避免了复杂的并发题目。
  • 浏览器是多线程的,它有多个辅助线程处置惩罚不同范例的使命(如定时器、网络哀求等)。
  • JavaScript 主线程将使命交给浏览器的辅助线程行止置惩罚,自己不阻塞,等这些使命完成后,结果会通过回调机制放回到主线程实行。整个异步机制是由 变乱循环使命队列 和谐的。
通过这种机制,JavaScript 可以在保持单线程的条件下高效地处置惩罚异步使命,而不影响页面的响应性。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

自由的羽毛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表