粗略理解 JavaScript的eventLoop

我们都知道JavaScript是单线程的语言,也就是在同一时间只能做一件事,就好比去银行办事,银行确只有一个办事窗口,人们必须一个一个排队,那么为什么要将JavaScript设计成单线程语言呢?我在网上大致看了下,基本上都是这么说的:

JavaScript作为浏览器脚本语言,如果采用多线程的设计方式,会产生一部分复杂的问题,举个例子就是两个线程同时操作一个DOM元素,一个线程是删除这个DOM元素,另一个线程是修改这个DOM,那么要以那个线程为准呢?

大致上都是这样的说法;

然而。。在HTML5中出现了一个API :Web Worker,他允许JavaScript在主线程以外另外创建一个线程,但是这个创建的线程不允许操作DOM元素而且还是完全受控于主线程的,所以这个API实际上并没有改变JavaScript是单线程的这一个特性;

  单线程意味着要排队,那么如果遇到了不确定耗时的任务怎么办呢?比如说现在我要发送一个请求,但是这个请求
往返的时间是不确定的,在请求的这段时间,难道要让用户一直等着吗?这对于用户的体验来说是十分不妙的,于是
同步和异步的概念就出来了,那么什么是同步,什么是异步呢?所谓的同步任务就是,老老实实的在主线程中排队执
行的事件;异步任务则是先不执行,而是将任务放入事件队列中,等待同步任务执行完成之后再回过头来执行事件队
列中的异步任务;

大致上的是这样的,比方说我们一起执行两个函数,第一个函数中有一个同步操作与一个异步操作,然后第二个函数中有一个异步操作

let fn1 = function(){
	setTimeout( () => {
		console.log('函数一:异步');
	},0);
	console.log('函数一:同步');
},
fn2 = function(){
	setTimeout( () => {
		console.log('函数二:异步')
	},0)
};
fn2();
fn1();

// 输出 '函数一:同步' -> '函数二:异步' -> '函数一:异步'

从这段代码中我们可以看到的是:

	在代码中我们先执行的是 fn2 这个函数,但是在这个函数中只有异步的定时器操作,所以JS将这个操作暂时存
入事件队列中,转而去执行了函数 fn1 ,在 fn1 函数中 'console.log('函数一:同步')';这一段是同步操作,
所以就算 setTimeout 定义在前面,JS 也会先将定时器存到事件队列中,去执行 'console.log('函数一:同步')'
这一段操作;也就是说这两个函数执行下来,JS的主线程中是只有 'console.log('函数一:同步')';这一段代码;
而在执行完这段之后,在查看主线程时,JS发现主线程的执行栈中已经没有待执行事件了,就转而去事件队列中将异
步事件,拉入执行栈中执行,由于先执行的 fn2 函数,所以先打印 '函数二:异步',最后打印 '函数一:异步';

然而在异步任务中,又分为了宏任务和微任务两种;

  • 宏任务

     定时器,AJAX; 这一类任务被定义为宏任务,宏任务的执行顺序是排在了微任务后;
    
  • 微任务

      Promise 的 then 就是微任务,但是要注意 new Promise中的操作是同步的操作;
    

所以最终的执行顺序是 同步 > 异步 ;
异步中: 微任务 > 宏任务;

	总的来说: 同步任务 > 微任务 > 宏任务;宏任务与微任务归类到异步任务中;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值