ajax请求会新建立一个线程吗,JavaScript是否会生成非阻塞AJAX的线程?

T.J. Crowder..

6

人们普遍认为JavaScript本质上是单线程的,但可以异步运行。

确实指定了JavaScript¹,使得在任何给定时间只能在一个域中执行单个线程。(领域是全局环境及其关联的对象;例如[浏览器上的窗口/选项卡。]您可以具有多个活动线程(在不同的窗口中,或通过Web worker),并且它们可以彼此通信(通过postMessage)甚至共享一些内存(SharedArrayBuffer),但他们无法同时访问同一领域。保持领域有效的单线程避免了大量的并发编程陷阱。

我想知道像这样的单线程模型如何处理非阻塞的AJAX请求?

JavaScript一次仅在JavaScript环境中只允许一个线程并不意味着主机(浏览器)是单线程的。异步ajax请求将移交给浏览器的网络处理。

JavaScript在作业队列的基础上工作(HTML5 speec称它为任务队列,但是JavaScript规范说的是“作业”,这只是名称)。JavaScript线程从队列中拾取一个作业,将该作业运行到完成,然后拾取下一个作业(如果有)。(比这要复杂一些,但这是基本思想。)当线程正在运行作业时,没有其他线程可以在同一领域中运行另一个作业。

因此,当ajax请求完成时(成功,超时等),浏览器(可能在非JavaScript线程上)会将一个作业放入JavaScript作业队列中,以调用ajax回调。JavaScript线程接收该作业并调用回调。

值得注意的是,这也正是它对发生的其他事情(例如用户单击某事)的反应。

假设在浏览器中触发了非阻塞AJAX请求,但没有立即得到响应。如果事件循环不断检查响应,执行是否不会被阻塞?

关键是线程不会连续检查返回的响应。该线程只监视作业队列。浏览器的网络处理程序处理网络请求的完成。

¹这是在ES2015中明确提出的,但在此之前的几年中,常见环境(浏览器,Node.js)就是这种情况。有一些JavaScript环境允许一个域中有多个线程(例如Rhino,在Java VM上运行JavaScript),但它们的重要性还不足以阻止ES2015添加此要求,因此允许围绕几个新功能定义精确的语义如果可能的话,要指定它本来要复杂得多,同时对线程主题保持沉默。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值