前提提要 系统内存在两个服务器的接口,一个是己方,一个是他方,某一天很多客户反应页面加载缓慢,但是最终会显示,经过排查,发现他方的接口一直处于pending状态,导致我方接口被迫挂起。 奇葩的是,超时不会报错!!! 登录对方的官网,发现也进不去。。。初步猜测是对方的服务器挂了,但是这种情况会返回相应的报错,然后猜测是对方的后端一直未返回数据。
排雷 网上说的几种情况: 1.并发量问题:浏览器对同一域名存在一个最大并发连接数,建议将资源分布在多台主机上(我们虽然调用了两个接口,但是不同域名,排除); 2.系统兼容或杀毒软件导致(win7系统其他客户也在使用,并且对方没有安装杀毒软件,排除);
结果 在整个排错的过程中,我一直奇怪一个点,为什么第二个请求被阻塞了呢?也怀疑是不是Electron的原因,然后开始百度,在文章 Electron的主进程阻塞导致UI卡顿的问题 中,看到这样一段话:
在chromium中,页面渲染时,UI进程需要和main process不断的进行sync IPC,若此时main process忙,则UI process就会在IPC时阻塞。
永远不要让主进程busy,怎么做? 马上能够想到:为了不让主进程busy,必须让有工作量的任务变成异步的,例如: 请求网页时,不用sync-request而是用异步的request。 读取文件时,不用fs.readFileSync(‘input.txt’),而是fs.readFile(‘input.txt’, function (err, data) {}
看到第二段,瞬间有种醍醐灌顶的感觉,我去确认了一下代码并看到ajax中有这样一句:async:false !!!(由于代码已经转手过N次,到我手里的时候可读性实在有点差,于是我只大体浏览了一遍,并完美的忽视了这句话)
讲解 async为true时是异步,为false时是同步,而JavaScript的事件循环是遇到同步任务放入主线程,直接执行,遇到异步任务则是放进任务队列,主线程的任务执行完成后,再读取任务队列的任务。所以当async:false是,这是一个同步任务,而这个同步任务一直没有返回值,导致阻塞
新增知识点 1.了解到有一个chrome有一个工具:chrome://net-internals ,用于帮助诊断网络请求与访问方面的问题; 2.单词:pending 代办;Stalled 停滞不前; 3.Ajax并发
Wininet 会限制每个服务器的连接数,限制它对单个 HTTP 服务器的同时连接的数量。如果超过此限制时,请求将阻止,直到完成当前的连接之一
4.执行中的线程:除了主线程之外,还有一个叫工作线程
主线程:也就是 js 引擎执行的线程,这个线程只有一个,页面渲染、函数处理都在这个主线程上执行。 工作线程:也称幕后线程,这个线程可能存在于浏览器或js引擎内,与主线程是分开的,处理文件读取、网络请求等异步事件。
更全面一点的话
JavaScript 单线程指的是浏览器中负责解释和执行 JavaScript 代码的只有一个线程,即为JS引擎线程,但是浏览器的渲染进程是提供多个线程的,如下:
- JS引擎线程:用于解析JavaScript代码
- 事件触发线程(onclick,onchange,…)
- 定时触发器线程(setTimeout, setInterval)
- 异步http请求线程:负责数据请求
- GUI渲染线程(它与javaScript线程是互斥的)
- EventLoop轮询处理线程:事件被触发时该线程会把事件添加到待处理队列的队尾
新增疑问
|