一道涉及宏任务和微任务的问题【同步和异步】

微任务、宏任务与Event-Loop

setTimeout(function(){
    console.log('1')
});
new Promise(function(resolve){
	console.log('2');
       resolve();
}).then(function(){
	 console.log('3')
});
console.log('4'); 

请你给出这段代码的运行顺序。

首先说一下普通的异步函数的执行过程吧:事件循环

在这里插入图片描述

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

但是js异步有一个机制,就是遇到宏任务,先执行宏任务,将宏任务放入事件队列event queue,然后在执行微任务,将微任务放入事件队列event queue

最骚的是,这两个事件不放在同一个队列 (这个queue不是一个queue)。当你往外拿的时候先从微任务事件队列里拿这个回调函数,然后再从宏任务的事件队列queue上拿宏任务的回调函数。

在这里插入图片描述

宏任务一般是:包括整体代码script,setTimeout,setInterval。
微任务:Promise,process.nextTick。

记住就行了。然后回到开头代码。

因为settimeout是宏任务,
虽然先执行的,但是他被放到了宏任务的event queue里面,
然后代码继续往下检查看有没有微任务,检测到Promise的then函数把他放入了微任务序列。

等到主线进程的所有代码执行结束后。

先从微任务queue里拿回调函数,然后微任务事件队列queue空了后再从宏任务的事件队列queue拿函数。

所以正确的执行结果当然是:2,4,3,1。

同步和异步的区别

同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。

异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。

同步,就是实时处理(如打电话),比如服务器一接收客户端请求,马上响应,这样客户端可以在最短的时间内得到结果,但是如果多个客户端,或者一个客户端发出的请求很频繁,服务器无法同步处理,就会造成涌塞。

同步如打电话,通信双方不能断(我们是同时进行,同步),你一句我一句,这样的好处是,对方想表达的信息我马上能收到,但是,我在打着电话,我无法做别的事情。

异步,就是分时处理(如收发短信),服务器接收到客户端请求后并不是立即处理,而是等待服务器比较空闲的时候加以处理,可以避免涌塞。

异步如收发收短信,对比打电话,打电话我一定要在电话的旁边听着,保证双方都在线,而收发短信,对方不用保证此刻我一定在手机旁,同时,我也不用时刻留意手机有没有来短信。这样的话,我看着视频,然后来了短信,我就处理短信(也可以不处理),接着再看视频。

对于写程序,同步往往会阻塞,没有数据过来,我就等着,异步则不会阻塞,没数据来我干别的事,有数据来去处理这些数据。

同步在一定程度上可以看做是单线程,这个线程请求一个方法后就待这个方法给他回复,否则他不往下执行(死心眼)。

异步在一定程度上可以看做是多线程的(废话,一个线程怎么叫异步),请求一个方法后,就不管了,继续执行其他的方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值