事件循环-队列的学习

84 阅读2分钟

事件循环-队列的学习

认识事件循环

/**
 * 事件循环:
 * 1.js线程(将耗时操作放到其他线程) -> 其他线程(开始计时/等待)
 * 2.其他线程(计时结束后,将回调函数放到事件队列) -> 事件队列(先进先出)
 * 3.事件队列(添加回调) -> js线程(js引擎不断的依次在队列中取出回调并在js线程执行)
 * 它们三个形成的闭环,称之为 事件循环.
 */
console.log('start~~');

// 业务代码
setTimeout(() => { // 内部的箭头函数是异步函数
  console.log('---');
}, 1000);

console.log('end~~');

宏任务和微任务

/**
 * 回调添加到事件队列中
 * 事件队列分为二个: 宏任务队列(macroTask)和微任务队列(microTask)
 * 宏任务队列: 定时器 / ajax / DOM / UI render / setInterval
 * 微任务队列: queueMicroTask / Promise的then回调
 * 执行顺序: 规范. 执行每个的宏任务之前,都需要先保证微任务队列已经被清空.
 */
setTimeout(() => {
  console.log('setTimeout');
}, 0);

// 队列微任务
queueMicrotask(()=>{
  console.log('queueMicrotask');
})
Promise.resolve(123).then(res=>{
  console.log(res);
})



// main script(全局的代码) , js线程最先执行这些代码
function bar() {
  console.log('bar');
}

function foo() {
  console.log('foo');
  bar()
}

foo()
console.log('其他代码~');

事件循环面试题一

setTimeout(function () {
  console.log("setTimeout1");
  new Promise(function (resolve) {
    resolve();
  }).then(function () {
    new Promise(function (resolve) {
      resolve();
    }).then(function () {
      console.log("then4");
    });
    console.log("then2");
  });
});

new Promise(function (resolve) {
  console.log("promise1");
  resolve();
}).then(function () {
  console.log("then1");
});

setTimeout(function () {
  console.log("setTimeout2");
});

console.log(2);

queueMicrotask(() => {
  console.log("queueMicrotask1")
});

new Promise(function (resolve) {
  resolve();
}).then(function () {
  console.log("then3");
});

// promise1
// 2
// then1
// queueMicrotask1
// then3
// setTimeout1
// then2
// then4
// setTimeout2

事件循环面试题二

// 把async当作普通的函数
async function async1 () {
  console.log('async1 start')
  await async2(); // 执行async2(),和await没有关系
  console.log('async1 end') // 这个代码是在then里执行的
}

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

事件循环面试题三

Promise.resolve().then(() => {
  console.log(0);
  // 1.直接return一个值 相当于resolve(4)
  // return 4
  // 2.return thenable的值
  // return {
  //   then: function(resolve) {
  //     resolve(4)
  //   }
  // }
  // 3.return Promise
  // 不是普通的值, 多加一次微任务
  // Promise.resolve(4), 多加一次微任务 
  // 一共多加两次微任务
  return Promise.resolve(4)
}).then((res) => {
  console.log(res)
})

Promise.resolve().then(() => {
  console.log(1);
}).then(() => {
  console.log(2);
}).then(() => {
  console.log(3);
}).then(() => {
  console.log(5);
}).then(() =>{
  console.log(6);
})

// 1.return 4
// 0
// 1
// 4
// 2
// 3
// 5
// 6

// 2.return thenable
// 0
// 1
// 2
// 4
// 3
// 5
// 6

// 3.return promise
// 0
// 1
// 2
// 3
// 4
// 5
// 6

Node的事件循环

/**
 * Node的事件循环是由libuv库实现的.
 * 微任务队列:process.nextTick(next tick queue) , Promise的then回调 / queueMicroTask(other queue)
 * 宏任务队列:setTimeout / setInterval(timer queue) , IO事件(poll queue) , setImmediate(check queue) , close事件(close queue)
 *
 * 
 * 按照下面顺序进行执行: 6个任务队列
 * next tick queue
 * other queue
 * timer queue
 * poll queue
 * check queue
 * close queue
 */

Node事件循环面试题四

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('setTimeout0')
}, 0)

setTimeout(function () {
  console.log('setTimeout2')
}, 300)

setImmediate(() => console.log('setImmediate'));

process.nextTick(() => console.log('nextTick1'));

async1();

process.nextTick(() => console.log('nextTick2'));

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

console.log('script end')

// script start
// async1 start
// async2
// promise1
// promise2
// script end
// nexttick1
// nexttick2
// async1 end
// promise3
// settimetout0
// setImmediate
// setTimeout2