【JavaScript】事件轮询

1、先参考搞懂 JavsScript 异步 —  事件轮询

2、明确几点:
  • setTimeoutDOM EventHttpRequestsetIntervalsetImmediate(Node.js独有)的回调、I/O操作、UI渲染均会被加载到消息队列(macrotask宏任务)。
  • Promise的回调、MutationObserverprocess.nextTick(Node.js独有)会被加载到任务队列(microtask微任务)。
  • 任务队列优先级高于消息队列,也就是微任务优先级高于宏任务。
3、例子
new Promise(function (resolve, reject) {
    resolve();
    setTimeout(function () {
        console.log(1);
    }, 0);
    console.log(2);
}).then(function () {
   	console.log(3);
}).then(function () {
   	console.log(4);
});
console.log(5); // 打印结果:2 5 3 4 1,其中setTimeout被加到消息队列,then回调被加到任务队列,先执行。

setTimeout(() => {
  console.log("200");
}, 200);
setTimeout(() => {
  console.log("100");
}, 100); // 100 200,等待执行的时间越短,越在队列前面,而不管在script中的顺序

setTimeout(() => {
  console.log("2");
}, 2);
setTimeout(() => {
  console.log("1");
}, 1); // 当等待时间过短时,或者说队列里两个item的间隔时间过短时,两者谁先执行并不确定,多数情况下打印1 2,即正常执行,少数情况下会打印 2 1

setTimeout(() => {
  console.log(1);
  new Promise((resolve, reject) => {
    console.log(2);
    resolve();
  })
    .then(() => {
      setTimeout(() => {
        console.log(4);
      });
      console.log(3);
    })
    .then(() => {
      console.log(7);
    });
  console.log(5);
});
console.log(6); // 6 1 2 5 3 7 4,任务队列新插入消息队列,要先等任务队列所有任务执行完成,再执行下一个消息队列

setTimeout(() => {
  console.log(1);
  new Promise((resolve, reject) => {
    console.log(2);
    resolve();
  })
    .then(() => {
      setTimeout(() => {
        new Promise((resolve, reject) => {
          console.log(4);
          resolve();
        }).then(() => {
          console.log(8);
        });
      });
      console.log(3);
    })
    .then(() => {
      console.log(7);
    });
  console.log(5);
});
console.log(6);  // 6 1 2 5 3 7 4 8,微任务属于宏任务,当前宏任务执行完才会执行下一个宏任务
posted @ 2023-11-07 20:35  unuliha  阅读(243)  评论(0编辑  收藏  举报