前端js同步、异步、任务队列、消息队列、宏任务、微任务的了解

本文深入探讨了JavaScript的执行机制,包括单线程、执行栈、主线程、消息队列、任务队列、同步与异步、事件轮询、微任务与宏任务的概念。通过实例解析了代码执行顺序,强调了异步处理的重要性,特别是Promise、async/await在处理异步操作中的应用。此外,还提供了相关面试题以加深理解。
摘要由CSDN通过智能技术生成

知识前置:

1.单线程(执行栈):在执行程序时,整体代码的执行由上而下,前面的执行完之后才能执行后面的。

详细解析: JavaScript 引擎是通过一种叫栈的数据结构来管理这些执行上下文。 在执行上下文创建好后,JavaScript 引擎会将执行上下文压入栈中,通常把这种用来管理执行上下文的栈称为执行上下文栈,又称调用栈

2.主线程:JS只有一个线程,这个线程负责解释和执行JS代码,称其为主线程,在这个主线程上,所有的代码按照顺序执行。

3.消息队列:消息队列里面放的是一些待触发执行的方法,如点击事件,当触发之后,会被通知主线程去执行

4.任务队列同步代码放到执行栈中执行,异步代码会先存放到任务队列中,执行栈代码先执行,异步代码在执行栈执行完后再执行。任务队列优先级高于消息队列

5.同步等待上一个事件执行完毕才执行下文,会阻塞,等待时间长,这种同步执行的操作容易使页面呈卡死状态,异步可以解决阻塞

6.异步(callback、Ajax、Promise、async await、nextTick()):不等前一个任务结束就执行。

详细解析:不进入主线程、而进入"任务队列"的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行

7.延迟函数执行(setTimeout、setInterval):等到执行栈清空的时候才会执行

8.事件轮询:先执行同步的的事件,监听执行栈,并确定执行栈是否为空。如果执行栈是空的(等同步的事件执行完),它就检查消息队列(异步的事件),消息队列的事件就会放入执行栈去执行,(简单来说执行栈有就执行,没有就不执行)

Js不存在异步,可以通过事件轮询实现异步,是单线程的。

JS的宿主环境(浏览器,node)存在异步,是多线程的。

优先级:同步>异步(任务队列>消息队列)>延迟函数

JavaScript中分为同步任务和异步任务,而异步任务中又分为宏任务和微任务两种,同一层级下,微任务永远比宏任务先执行

9.微任务(Promise、async/await、process.nextTick):执行完当前主线程任务后就要马上执行的任务

10.宏任务(setTimeout、setInterval、Ajax、事件绑定):可以理解是每次执行栈执行的代码就是一个宏任务

做题技巧

1.new Promise是一个构造函数,是同步任务

2.Promise.resolve().then 是微任务

3.async是同步任务

4.await方法返回的是一个Promise对象,后面相当于Promise then, 是微任务

5.定时器,加入下一次宏任务,是宏任务

简单题:

1.

console.log('aaaa');

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

console.log('bbbb');

解析:先同步后异步(setTimeout)

答案: aaaa  bbbb cccc

2.

console.log('aaa');

setTimeout(() => console.log(111), 10);
setTimeout(() => console.log(222), 0);

console.log('bbb');

解析:先同步后异步,延迟异步(setTimeout)

答案: aaa  bbb 222 111 

3.

console.log('aaa');

(async ()=>{
  console.log(111);  //在async里面
})().then(()=>{
  console.log(222);  //在async的then里面
});

console.log('bbb');

 

解析:先同步后异步,异步分宏任务、微任务,同级先微后宏

(async是同步任务,Promise.resolve().then是异步微任务)

答案: aaa 111   bbb  222

4.

console.log('aaa');

(async ()=>{
  console.log(111);
  await console.log(222);
  console.log(333);
})().then(()=>{
  console.log(444);
});

console.log('ddd');

 

解析:先同步后异步,异步分宏任务、微任务,同级先微后宏

(async是同步任务,await 的console.log是同步的,所以会立即执行,await本身就是then,所以console.log(333)无法直接执行)

答案: aaa 111 222 ddd 333 444

5.

console.log('aaa');


setTimeout(()=>console.log('t1'), 0);


(async ()=>{
  console.log(111);
  await console.log(222);
  console.log(333);

  setTimeout(()=>console.log('t2'), 0)
  })().then(()=>{
  console.log(444);
  })


console.log('bbb');

 

答案: aaa 111 222  bbb  333  444  t1  t2

面试题:

1.滴滴智能中台

setTimeout(function(){  
 console.log('1') 
}); 


 new Promise(function(resolve){ 
    console.log('2')
    for (var i = 0; i < 10000; i++){ 
       i == 99 && resolve()
    }}).then(function(){ 
    console.log('3')}
    )


 console.log('4');

 

答案:2 4 3  1

2.小米前端实习面经

 //执行顺序
   async function async1() {
           console.log('async1 start')
           await async2();
           console.log('async1 end')
       }

       async function async2() {
           console.log('async2')
       }

       console.log('script start')

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

       async1();
       
       new Promise(
           function (resolve) {
               console.log('promise1')
               resolve();
           })
           .then(
               function () {
                   console.log('promise2')
               })
       console.log('script end')

答案:

script start

async1 start

async2

promise1

script end

async1 end

promise2

setTimeout

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值