十九、JS中的同步异步(Event Loop)------ 2020-01-20

1、浏览器执行JS代码的机制:

/**
(1)、首先,浏览器是多线程的,但是JS是单线程的;
(2)、浏览器执行JS代码时,会分配出一个主线程执行JS代码,当JS代码中出现异步代码时,
浏览器会将异步代码加入 等待任务队列(Event Queue)中,当主线程把要执行的代码执行
完毕后,会进入到 等待任务队列中,将异步代码按照一定的规则执行;
*/ 

2、等待任务队列(Event Queue):

/**
(1)等待任务队列是指主线程执行代码时,遇到的异步执行代码将异步代码放置的地方,
等待主线程空闲时再执行这个异步代码;相当于一个堆内存,存放等待执行的代码;
等待任务队列分为:宏任务队列和微任务队列;
(2)宏任务队列(macro task queue):定时器、事件绑定、Ajax;
(3)微任务队列(micro task queue):Promise、Async/await......;
*/

3、简单例子(未区分宏任务、微任务):

setTimeout(() => {
 console.log(1)
}, 50);

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

console.time('FOR');

for (let i = 0; i < 100000000; i++) {
  
}

console.timeEnd('FOR');

setTimeout(() => {
 console.log(3)
}, 20);

console.log(4);

/**
这个执行结果有两种情况:
(1)如果for循环耗时小于50ms和20ms定时器的差值,那么当for循环执行完毕后,将20ms定时器
推入到Event Queue后,还是20ms定时器先到达执行时间;执行结果就是:4,2,3,1;
(2)如果for循环耗时大于50ms和20ms定时器的差值,那么当for循环执行完毕后,50ms定时器的
剩余时间小于20ms,此时20ms定时器才刚刚推进Event Queue中,刚开始计时,所以执行结果是:
4,2,1,3
*/
Event Loop.png

4、经典面试题(区分宏任务、微任务):

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');
宏任务、微任务.png

你可能感兴趣的:(十九、JS中的同步异步(Event Loop)------ 2020-01-20)