编程语言
首页 > 编程语言> > javascript事件循环

javascript事件循环

作者:互联网

-

javascript事件循环机制从何而来(产生原因):

因为javascript是单线程的,javascript自上而下执行,但是不一定都是同步代码,中间会遇到一些异步的代码,比如定时器。那么这时候,单线程的javascript该如何应对呢?

于是就想了个解决办法,用事件循环(event loop)来应对异步。

 

补充:为什么javascript会被设计成单线程?

假如说。javascript是多线程的,有两个线程同时去操作一个DOM,期中一个对这个DOM加一个属性,而另一线程要删除这个DOM,那么以哪个线程为准呢?这样就会产生许多复杂的问题要处理,

所以就设计成单线程最合理。虽然h5,提出了web worker新标准,但是它受主线程限制,它是主线程的一个子线程。

 

下面来说一下javascript 事件循环机制(event loop)

1、执行栈

2、事件队列(任务队列)

  任务又分为宏任务和微任务

 

 

 

事件队列: 异步代码的执行,遇到异步事件不会等待它返回结果,而是将这个事件挂起,继续执行执行栈中的其他任务。当异步事件返回结果,将它放到事件队列中,被放入事件队列不会立刻执行起回调,而是等待当前执行栈中所有任务都执行完毕,主线程空闲状态,主线程会去查找事件队列中是否有任务,如果有,则取出排在第一位的事件,并把这个事件对应的回调放到执行栈中,然后执行其中的同步代码。

 

主线程会依次执行执行栈内的代码,遇到异步代码(宏任务|微任务),就会将它们放到事件队列中(任务队列中),如果是宏任务,就放在宏任务队列,如果是微任务,就放在微任务队列。

如果主执行栈执行完毕,会从事件队列中去取事件,放在执行栈中执行。

事件队列遵守先进先出原则。

先执行宏任务,如果本次宏任务执行产生了微任务,会先把这个微任务执行完,再执行下一个宏任务

 

宏任务有哪些?

微任务有哪些?

 

简单总结一下顺序

执行宏任务,然后执行该宏任务产生的微任务,若微任务在执行过程中产生了新的微任务,则继续执行微任务,微任务执行完毕后,再回到宏任务中进行下一轮循环。

 

练习一道题:

console.log('start')

setTimeout(function() {
  console.log('setTimeout')
}, 0)

Promise.resolve().then(function() {
  console.log('promise1')
}).then(function() {
  console.log('promise2')
})

console.log('end')

执行顺序:

1、全局代码压入执行栈执行,输出 start

2、setTimeout压入 macrotask队列,promise.then 回调放入 microtask队列,最后执行 console.log('end'),输出 end

3、调用栈中的代码执行完成(全局代码属于宏任务),接下来开始执行微任务队列中的代码,执行promise回调,输出 promise1, promise回调函数默认返回 undefined, promise状态变成 fulfilled ,触发接下来的 then回调,继续压入 microtask队列,此时产生了新的微任务,会接着把当前的微任务队列执行完,此时执行第二个 promise.then回调,输出 promise2

4、此时,microtask队列 已清空,接下来会会执行 UI渲染工作(如果有的话),然后开始下一轮 event loop, 执行 setTimeout的回调,输出 setTimeout

 

最后输出结果:

 

-

标签:setTimeout,队列,javascript,任务,循环,事件,执行,事件队列
来源: https://www.cnblogs.com/fqh123/p/15255338.html