【javascript】【异步事件】怎么理解js是单线程的,但又可以实现异步编程

js的异步事件通常包括以下几类:
网络请求:ajax请求,服务端响应(随时发生)
计时器:setTimeOut,setTimeInterval(定时发生)
用户事件:鼠标,键盘,控件(随时发生)
浏览器事件:页面加载完毕,页面加载失败(随时发生)
以上情况下,代码的执行事件都是不确定的,或者不是立刻执行的,不可能由单线程来完成

js是单线程的,指的是javascript语言是单线程的,不支持创建新的线程来执行事件
但是浏览器可以创建多个js线程,从而实现异步功能
假设把js事件队列所在的线程称为【事件处理线程/主线程】,把控制异步事件执行时机的线程称为【事件触发线程/异步工作线程】
我们来分析下常见的异步情景下,javascript是如何运行的

ajax请求
主线程从事件队列中取到ajax请求事件,将ajax请求转给异步工作线程去处理,自己继续处理队列中的其它事件
异步工作线程发出ajax请求,并等待服务端响应,当服务端返回响应时,将ajax回调事件加入到主线程的事件队列中
主线程按顺序处理事件队列中的事件,直到遇到ajax回调事件,将其取出执行

setTimeOut
主线程将定时任务交给异步工作线程
异步工作线程开始等待,到达指定时间,将setTimeOut回调事件加入到主线程的事件队列中
主线程按顺序处理事件队列中的事件,直到遇到setTimeOut回调事件,将其取出执行

setTimeInterval
主线程将定时任务交给异步工作线程
异步工作线程开始等待,到达指定时间,将setTimeInterval回调事件加入到主线程的事件队列中
异步工作线程重复以上过程,每隔一定时间,就向主线程的事件队列加入一个回调事件
主线程按顺序处理事件队列中的事件,每遇到一个setTimeInterval回调事件,就将其取出执行

从以上过程我们可以发现:
在异步工作线程中,定时是精确的,到达指定时间,就向主线程事件队列加入回调事件
但是在主线程中,因为事件队列是按顺序处理的,必须处理完前面的所有事件,才能执行回调事件,执行时间完全是不可控的
所以js的定时器是不精确的,设定的时间,只是将回调事件加入到事件队列中的时间

猜你喜欢

转载自blog.csdn.net/u013718730/article/details/80480669