【内容梳理】<JS>事件循环

43 阅读2分钟

1. 同步任务

主线程按代码顺序执行,前一个任务执行完才执行下一个任务

const func1 = () => {
  console.log('1-1');
};

const func2 = () => {
  console.log('2-1');
};

console.log('0-1');

window.alert('alert test');

func1();

window.confirm('confirm test');

console.log('0-2');

window.prompt('prompt test');

func2();

同步测试.gif

2. 异步任务

  • 异步任务分为宏任务微任务
  • 微任务先执行,微任务栈空后,再执行宏任务
  • 微任务包含:process.nextTick(Node中)promiseMutationObserver
  • 宏任务包含:postMessageMessageChannelsetTimeoutsetIntervalsetImmediate(Node中)I/OUI renderingEvent Handlers
  • 微任务宏任务一般秉持先解析先入栈的准则,但也有特殊,比如process.nextTick(Node中),会插入到当前微任务的最前面,如果已经有process.nextTick(Node中),则往后排

3. 实战

  • 简单回顾

事件循环.gif

  • 题目一
function takeLongTime(delay, consoleStr) {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(consoleStr);
      resolve(consoleStr);
    }, delay);
  });
}

const test1 = async () => {
  console.log('执行test1中---');
  await takeLongTime(1000, 'test1A');
  console.log('执行完成test1A---');
  await setTimeout(() => {
    console.log('test1B');
  }, 1000);
  console.log('test1C');
};

const test2 = async () => {
  console.log('执行test2中---');
  await takeLongTime(500, 'test2A');
  console.log('执行完成test2A---');
  await setTimeout(() => {
    console.log('test2B');
  }, 500);
  console.log('test2C');
};

console.log('主线程执行test1');
test1();
console.log('主线程执行test2');
test2();
console.log('本次主线程结束');

// 主线程执行test1
// 执行test1中---
// 主线程执行test2
// 执行test2中---
// 本次主线程结束
// test2A
// 执行完成test2A---
// test2C
// test1A
// 执行完成test1A---
// test1C
// test2B
// test1B
  • 题目二
async function async1() {
  console.log('1-1');
  await async2();
  console.log('1-2');
}
async function async2() {
  console.log('2');
}

async function async3() {
  console.log('3-1');
  await async4();
  console.log('3-2');
}
async function async4() {
  console.log('4');
}

console.log('0-1');
async1();
console.log('0-2');
async3();
console.log('0-3');

// 0-1
// 1-1
// 2
// 0-2
// 3-1
// 4
// 0-3
// 1-2
// 3-2
  • 题目三
let a: number = 0;

const test1 = () => {
  new Promise((resolve: (value: number) => void) => {
    resolve(a + 1);
    console.log('==test 1==', a);
  }).then((res) => {
    a = res + a;
    console.log('==test 2==', a);
  });
  setTimeout(() => {
    console.log('==test 3==', a++);
  }, 1000);
  new Promise((resolve: (value: number) => void) => {
    resolve(a++);
    console.log('==test 4==', a);
  }).then((res) => {
    a = a + res;
    console.log('==test 5==', a);
  });
};

const test2 = async () => {
  setTimeout(() => {
    a = a + 10;
    console.log('==test 6==', a);
  }, 500);
  a = a + (await 10);
  console.log('==test 7==', a);
  a = (await 10) + a;
  console.log('==test 8==', a);
};

test1();
//
process.nextTick(() => {
  a++;
  console.log('==test 9==', a);
});
//
test2();
//
a++;
console.log('==test 10==', a);
//
process.nextTick(() => {
  console.log('==test 11==', a++);
});
//
Promise.resolve(10).then((res) => {
  a = a + res;
  console.log('==test 12==', a);
});

// ==test 1== 0
// ==test 4== 1
// ==test 10== 2
// ==test 9== 3
// ==test 11== 3
// ==test 2== 5
// ==test 5== 5
// ==test 7== 11
// ==test 12== 21
// ==test 8== 31
// ==test 6== 41
// ==test 3== 41

线程.png