js 的特点 单线程 执行机制是基于 event loop 所有同步任务再主线程执行,形成执行栈 主线程之外有一个任务队列,只要一步任务有了运行结果,就在任务队列中放置一个事件 一旦执行栈的同步执行完毕,就去读取任务队列,寻找任务队列中放置的异步事件,异步事件结束等待状态,进入执行栈,开始执行 之前有写了一篇文章 js 引擎执行过程:运行机制,语法分析,创建函数调用栈,创建上下文,创建作用域链 ,…

js 的特点

  • 单线程
  • 执行机制是基于 event loop
    • 所有同步任务再主线程执行,形成执行栈
    • 主线程之外有一个任务队列,只要一步任务有了运行结果,就在任务队列中放置一个事件
    • 一旦执行栈的同步执行完毕,就去读取任务队列,寻找任务队列中放置的异步事件,异步事件结束等待状态,进入执行栈,开始执行

之前有写了一篇文章js 引擎执行过程:运行机制,语法分析,创建函数调用栈,创建上下文,创建作用域链,用于理解 js 的运行机制

微任务和宏任务都有哪些

  • 微任务
    • process.nextTick(服务端的方法)
    • Promise 的 then,catch,finally 等
    • MutationObserver(MutationObserver 接口提供了监视对 DOM 树所做更改的功能)
  • 宏任务
    • setTimeout
    • setInterval
    • setImmediate(目前只有 Internet Explorer 10 实现了该方法)
    • requestAnimationFrame(告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画)

微任务和宏任务的特点

微任务的执行早于宏任务

  • setTimeout 与 promise
setTimeout(() => console.log(1), 0);
console.log(2);
new Promise(resolve => {
  resolve();
  console.log(3);
}).then(() => {
  console.log(4);
  Promise.resolve()
    .then(() => {
      console.log(5);
    })
    .then(() => {
      Promise.resolve().then(() => {
        console.log(6);
      });
    });
});
console.log(7);
// 结果
// 2, 3, 7, 4, 5, 6, 1;
  • dom 中的微任务与宏任务
function handler() {
  // 宏任务
  setTimeout(() => console.log('setTimeout'));
  // 微任务
  Promise.resolve().then(() => console.log('Promise'));
  // 宏任务
  requestAnimationFrame(() => console.log('requestAnimationFrame'));
  console.log('click');
  // 触发MutationObserver
  document.querySelector('#box').setAttribute('data-name', 'koa');
}
new MutationObserver(() => {
  // 微任务
  console.log('MutationObserver');
}).observe(document.querySelector('#box'), {
  attributes: true
});
document.querySelector('#box').addEventListener('click', handler);
// 结果
// click, Promise, MutationObserver, requestAnimationFrame, setTimeout;
  • setTimeout 与 async/await

    async/await 本质是 Promise 的语法糖

setTimeout(() => console.log(1));
var p = new Promise((resolve, reject) => {
  console.log(2);
  resolve(3);
});
async function main() {
  console.log(4);
  const result = await p.then();
  console.log(result);
}
main();
console.log(5);
setTimeout(() => console.log(6), 0);
// 结果
// 2, 4, 5, 3, 1, 6
  • setTimeout 与 Vue.nextTick
    1. Vue.nextTick 本质也是一个 promise,是微任务,
    2. 先把 tick1 放入队列中,然后放 timer2 到队列;主线程执行完,又因为微任务总是早于宏任务执行,所以先执行 tick1,tick1 里面又是 timer1,把 timer1 push 到队列中;再执行 timer2,timer2 里面是 tick2,把 tick2 push 到队列,又因为微任务总是早于宏任务执,所以先执行 tick2,然后执行 timer1。最终的结果就是 1,4,7,5,2,3,6
console.log(1);
var timer2 = setTimeout(function() {
  console.log(2);
  // tick2
  Vue.nextTick(function() {
    console.log(3);
  });
}, 0);
console.log(4);
// tick1
Vue.nextTick(function() {
  console.log(5);
  var timer1 = setTimeout(function() {
    console.log(6);
  }, 0);
});
console.log(7);
// 结果
// 1, 4, 7, 5, 2, 3, 6;

暂无评论