JS执行机制,结合案例一看就懂

javascript分为同步任务和异步任务。

打开网站时,网页的渲染过程就是同步任务,比如页面骨架和页面元素的渲染。

而像加载图片音乐之类占用资源大耗时久的任务,一般来说就是异步任务

以下为javascript事件循环图

先执行同步任务,再执行异步任务

let data = [];
$.ajax({
  url:www.javascript.com,
  data:data,
  success:() =>{
     console.log('发送成功');
  }
})

console.log('代码执行结束');

上面是一段简易的ajax代码:

(1) ajax进入Event Table,注册回调函数success

(2) 执行console.log('代码执行结束')

(3)ajax事件完成,回调函数success进入Event Queue。

(4)主线程从Event Queue读取回调函数success并执行。

SetTimeout:

// 延时3秒执行

setTimeout(() => {
  console.log('延时3秒');
},3000)
setTimeout(()=>{
  task();
},3000)

console.log('执行console')

先执行console,再执行task(),如果console部分代码用时很久,则task执行时间会超过3秒。

setTimeout(()=>{
  task();
},3000)

sleep(1000000)

需要等sleep(100000)执行完毕后,task()才会执行,所以task()执行延迟不止3秒

我们还经常遇到setTimeout(fn,0)这样的代码,0秒后执行又是什么意思呢?是不是可以立即执行呢?

不会立即执行setTimeout(fn,0)的含义是

指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行。

举例:

console.log('logAAA')

setTimeout(()=>{
  console.log('setAAA')
},0);


//  logAAA  setAAA



setTimeout(()=>{
  console.log('setBBB')
},0);

console.log('logBBB')


//  logBBB  setBBB

JS先执行同步代码,再执行异步代码,所以不论setTimeout写在前还是后,都是先执行console

SetInterval:

对于setInterval(fn,ms)来说,我们已经知道不是每过ms秒执行一次fn,而是每过ms秒就会有fn进入Event Queue。

一旦setInterval的回调函数fn执行时间超过了延时时间,那么就完全看不出来有时间间隔了。


除了广义的同步任务和异步任务外,我们对任务还有更精细的定义:

  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval

  • micro-task(微任务):Promise.then,process.nextTickobject.observe

不同类型的任务会进入对应的Event Queue,

比如setTimeoutsetInterval会进入相同的Event Queue(事件队列)

事件循环的顺序,决定js代码的执行顺序。

进入一次整体代码执行宏任务后,开始第一次循环。

直接执行所有的微任务。

然后再次从宏任务开始,找到其中一个任务队列执行完毕。

再执行所有的微任务。

setTimeout(()=>{
 console.log('setTimeout')
})

new Promise((resolve)=>{
   console.log('promise')
}).then(()=>{
   console.log('then');
})

console.log('console')


//  输出顺序为: promise  --> console --> then --> setTimeout

(1) 这段代码做为宏任务,进入住线程

(2)先遇到setTimeout,将其回调函数注册后分发到宏任务Event Queue

(3)接下来遇到Promise,newPromise立即执行,then函数分发到微任务Event Queue。

(4)遇到console,立即执行

(5)此时,整体代码做为第一个宏任务执行结束,看看有哪些微任务,

    发现then在微任务Event Queue里面,执行。

(6)第一轮事件循环结束,开始第二次事件循环,从宏任务Event Queue开始,发现setTimeout。

(7)结束

 

 //1 7 6 8 2 4 3 5 9 11 10 12

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值