js事件轮询:
1、js 是一门单线程语言,从上往下执行的,首先,主线程读取js代码,此时是同步的环境
2、当主线程检测到异步操作,就会交给其他异步线程处理,然后继续执行主线程的的任务
3、异步任务执行完毕之后,判断异步任务的类型,异步任务可分成宏任务和微任务,像setTimeout、setInterval属于宏任务,promise.then属于微任务,不同的任务进入不同的队列,等待主线程空闲时候调用。
4、当主线程的的同步任务执行完毕之后,开始执行微任务队列里面的所有微任务,执行完微任务,就执行宏任务队列里面所有的宏任务
5、执行完成之后,主线程开始询问任务队列里面是否还有等待的任务,如果有则进入主线程继续执行
以上步骤重复执行就是事件轮询
js将异步队列里的任务划分为宏任务和微任务
宏任务有:1)setTimeout, setInterval, setImmediate,2)I/O、3)、UI rendering等
微任务有:1)process.nextTick、2)Promise、3)Object.observe(已废弃)、4)MutationObserver(html5新特性)等
举个例子
console.log('script start') setTimeout(function(){ console.log('setTimeOut') }, 0) new Promise(function(resolve){ console.log('promise1') resolve() }).then(function(){ console.log('promise2') }) console.log('script end')
流程如下:
1、打印script start,
2、遇到setTimeout放到宏任务队列里
3、打印promise1
4、将.then回调放入微任务队列里
5、打印script end
6、执行栈已清空,执行微任务队列打印promise2
7、微任务队列已清空,执行宏任务队列setTimeOut
8、所有任务队列清空
(如果还有任务的话则继续轮询 微任务 => 宏任务 => 微任务 => 宏任务…)
promise里的是同步代码,.then里的才是异步的
————————————————
原文链接:https://blog.csdn.net/zhou981130/article/details/117691434
在实际开发中,经常会有轮询的效果。
1、js实现轮询效果==>使用setTimeout,clearTimeout方法
function setTimer () { let timer = null axios.post(url, params).then(res=>{ if(res){//根据返回状态判断 timer = setTimeout(()=>{ this.setTimer () },2000)//2秒查一下 }else{ clearTimeout(timer);//清理定时任务 } }) .catch((error)=> { console.log(error); }); }
2.HTML5推出新的对象:websocket
js setInterval+setTimeout定时器轮询+终止轮询
常见的轮询方式:
window.timer = setInterval(()=>{ this.promiseFun() },1000)
大家一般都会使用setInterval,但要注意单纯使用它可能导致页面卡死。
原因是setInterval不会清除定时器队列,每重复执行1次都会导致定时器叠加,卡死。但是setTimeout是自带清除定时器的所以可以叠加使用。
更好的轮询方式
window.timer = setInterval(() => { setTimeout(this.promiseFun(), 0) }, 1000)
结束轮询
在需要结束轮询的时候,如果是vue可以在beforeDestroy生命周期函数中销毁定时器
clearInterval(timer)
摘自:
https://www.jianshu.com/p/d8809c698bc4
https://www.jb51.net/article/216449.htm
https://www.niceym.com/29421.html