首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript 事件循环机制

JavaScript 事件循环机制

作者头像
Jimmy_is_jimmy
发布2019-07-31 16:56:23
4680
发布2019-07-31 16:56:23
举报
文章被收录于专栏:call_me_Rcall_me_R

javascript是一门单线程的非阻塞的脚本语言。单线程意味着javascript在执行代码的任何时候,都只有一个主线程来处理所有的任务。

那么javascript引擎是如何实现这一点的呢?

因为事件循环(event loop)。先上图:

图片解读:

  • 同步和异步任务分别进入不同的执行场所,同步的进入主线程,异步的进入Event Table并注册函数
  • 当指定的事情完成时(重点)Event Table会将这个函数移入Event Queue
  • 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行
  • 上述的过程会不断的重复,也就是常常说的Event Loop(事件循环)

简单例子

我们来一个简单的例子来说明下:

console.log('1');
setTimeout(() => {
	console.log('2');
}, 0)
console.log('3');
复制代码

上面的代码将输出下面的结果:

1
3
2

因为setTimeout是一个异步的任务,所以会在最后才执行。

那么,我们来个复杂点的例子:

复杂例子

 console.log('1');
 setTimeout(() => {
 	console.log('2')
 }, 1000);
 new Promise((resolve, reject) => {
 	setTimeout(() => {
 		console.log('3');
 	}, 0);
 	console.log('4');
 	resolve();
 	console.log('5');
 }).then(() => {
 	console.log('6');
 });
 console.log('7');
复制代码

上面的代码输出的结果是:

1
4
5
7
6
3
2

看到这代码的时候是不是有些蒙圈?在我们揭开谜底之前,先来了解下微任务和宏任务

微任务和宏任务

微任务和宏任务都是异步的任务,他们都属于队列,主要区别是它们的执行顺序--微任务会比宏任务先执行。

宏任务包含有:setTimeout, setInterval, setImmediate, I/O, UI rendering

微任务包含有:process.nextTick, promise.then, MutationObserver

嗯~回到上面的代码,如下:

 console.log('1');
 setTimeout(() => {
 	console.log('2')
 }, 1000);
 new Promise((resolve, reject) => {
 	setTimeout(() => {
 		console.log('3');
 	}, 0);
 	console.log('4');
 	resolve();
 	console.log('5');
 }).then(() => {
 	console.log('6');
 });
 console.log('7');
复制代码

在执行到new Promise的时候会立马新建一个promise对象并立即执行。所以会输出 1,4,5,而then则会在Event Table中注册成回调函数并放在微任务队列中,而两个setTimeout(输出3)和setTimeout(输出2,1s后完成的啊)会被先后注册成回调函数并放在宏任务队列中。

理解了上面的一些原理之后,我们再来练下手...

console.log(1)
process.nextTick(() => {
  console.log(8)
  setTimeout(() => {
    console.log(9)
  })
})
setTimeout(() => {
  console.log(2)
  new Promise(() => {
    console.log(11)
  })
})
let promise = new Promise((resolve,reject) => {
  setTimeout(() => {
    console.log(10)
  })
  resolve()
  console.log(4)
})
fn()
console.log(3)
promise.then(() => {
  console.log(12)
})
function fn(){
  console.log(6)
}
复制代码

得到的结果是:

1
4
6
3
8
12
2
11
10
9

客官可以画下图整理下思路,然后代码运行验证一下啊?

参考&后话

文章首发javascript事件循环机制,更多的内容,请戳我的博客进行了解,能留个star就更好了?

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简单例子
  • 复杂例子
    • 微任务和宏任务
    • 参考&后话
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档