初稿地址:

职分队列

主线程:正在推行的代码,会生成函数调用栈。

职分队列

  • 主线程:正在实施的代码,会生成函数调用栈。
  • macro-task(宏职责,新名:task)包蕴:script(全部代码), setTimeout,
    setInterval, setImmediate, I/O, UI rendering。
  • micro-task(微职分,新名:jobs)包含: process.nextTick, Promise,
    Object.observe(已吐弃),
    MutationObserver(html五新特色,队列中不得不有多少个)
  • macro-task(宏任务,新名:task)包涵:script(全部代码), setTimeout,
    setInterval, setImmediate, I/O, UI rendering。
  • micro-task(微职分,新名:jobs)包含: process.nextTick, Promise,
    Object.observe(已扬弃),
    MutationObserver(html5新特征,队列中不得不有1个)

职责分类

  • 协助进行任务,语句只按语句先后顺序实行,后边未进行完,不会施行后边语句。
  • 异步任务,语句不在语句先后顺序上实行,实施到该代码时,加入到相应任务队列,延后实行。

职分分类

单线程

主线程从 script
(全体代码)开首率先次巡回。之后全局上下文进入函数调用栈。直到调用栈清空(只剩全局),然后实行全部的
jobs。当全体可进行的 jobs 推行完结之后。循环重复从 task
早先,找到当中一个职务队列实践完结,然后再推行全数的
jobs,这样直接循环下去。

联合职责,语句只按语句先后顺序实践,前边未推行完,不会推行前边语句。

注意事项

  • setTimeout 最小间隔不能低于 四 皮秒,不然会活动扩充。
  • DOM 的渲染每 1陆 皮秒实行二次,因为荧屏是 60 Hz,1陆ms 刷新三次。
  • process.nextTick 职责会在 jobs 里单独维护2个行列,并且在其余 jobs
    任务在此以前实践。
  • 冒泡事件会一贯在子元素事件实践到位后,插入在主线程中。若是主线程不为空,那么会先行于
    jobs 实行。

异步任务,语句不在语句先后顺序上进行,施行到该代码时,参加到对应职务队列,延后奉行。

经文示例

示范详解:

单线程

通过鼠标点击

<div class="outer">
  <div class="inner"></div>
</div>

// Let's get hold of those elements
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');

// Let's listen for attribute changes on the
// outer element
new MutationObserver(function() {
  console.log('mutate');
}).observe(outer, {
  attributes: true
});

// Here's a click listener…
function onClick() {
  console.log('click');

  setTimeout(function() {
    console.log('timeout');
  }, 0);

  Promise.resolve().then(function() {
    console.log('promise');
  });

  outer.setAttribute('data-random', Math.random());
}

// …which we'll attach to both elements
inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);

// 输出结果
click
mutate
click
mutate
promise
promise
timeout
timeout

主线程从 script
(全体代码)早先率先次巡回。之后全局上下文进入函数调用栈。直到调用栈清空(只剩全局),然后施行全数的
jobs。当有着可实行的 jobs 实施完成之后。循环重复从 task
发轫,找到当中多个职责队列施行达成,然后再施行全部的
jobs,那样间接循环下去。

进阶–通过js执行

<div class="outer">
  <div class="inner"></div>
</div>

// Let's get hold of those elements
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');

// Let's listen for attribute changes on the
// outer element
new MutationObserver(function() {
  console.log('mutate');
}).observe(outer, {
  attributes: true
});

// Here's a click listener…
function onClick() {
  console.log('click');

  setTimeout(function() {
    console.log('timeout');
  }, 0);

  Promise.resolve().then(function() {
    console.log('promise');
  });

  outer.setAttribute('data-random', Math.random());
}

// …which we'll attach to both elements
inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);
inner.click();

// 输出结果
click
click
mutate
promise
promise
timeout
timeout

由于点击事件是 js 实施的,inner 的 onClick 函数试行到位时,inner.click()
语句的功效域还尚无退栈,主线程调用栈不是空的,导致 jobs
队列职分不会实行,mutate 和 promise
语句都无法在事件循环中实行到。从而实施了 outer 的 onClick 函数。outer 的
onClick 函数施行到位后,inner.click() 语句才退栈,继而施行 jobs 的职务。

唯有叁个 mutate 是出于 jobs 队列中,只好有3个 MutationObserver
职务,第3遍创立时,前一个 MutationObserver 任务未有实施,顾不再次创下制。

注意事项

  • set提姆eout 最小间隔无法低于 四 阿秒,不然会自行增添。
  • DOM 的渲染每 16 阿秒实施二次,因为显示器是 60 Hz,1陆ms 刷新1次。
  • 永利开户送38元体验金,process.nextTick 职务会在 jobs 里单独维护3个行列,并且在别的 jobs
    职分在此之前实践。
  • 冒泡事件会直接在子成分事件试行到位后,插入在主线程中。假若主线程不为空,那么会优先于
    jobs 推行。

经文示例

示范详解:

经过鼠标点击

<div class="outer">
 <div class="inner"></div>
</div>
// Let's get hold of those elements
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
// Let's listen for attribute changes on the
// outer element
new MutationObserver(function() {
 console.log('mutate');
}).observe(outer, {
 attributes: true
});
// Here's a click listener…
function onClick() {
 console.log('click');
 setTimeout(function() {
  console.log('timeout');
 }, 0);
 Promise.resolve().then(function() {
  console.log('promise');
 });
 outer.setAttribute('data-random', Math.random());
}
// …which we'll attach to both elements
inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);
// 输出结果
click
mutate
click
mutate
promise
promise
timeout
timeout

进阶–通过js执行

<div class="outer">
 <div class="inner"></div>
</div>
// Let's get hold of those elements
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
// Let's listen for attribute changes on the
// outer element
new MutationObserver(function() {
 console.log('mutate');
}).observe(outer, {
 attributes: true
});
// Here's a click listener…
function onClick() {
 console.log('click');
 setTimeout(function() {
  console.log('timeout');
 }, 0);
 Promise.resolve().then(function() {
  console.log('promise');
 });
 outer.setAttribute('data-random', Math.random());
}
// …which we'll attach to both elements
inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);
inner.click();
// 输出结果
click
click
mutate
promise
promise
timeout
timeout

鉴于点击事件是 js 实践的,inner 的 onClick 函数执行到位时,inner.click()
语句的效率域还从未退栈,主线程调用栈不是空的,导致 jobs
队列任务不会举行,mutate 和 promise
语句都不许在事变循环中奉行到。从而施行了 outer 的 onClick 函数。outer 的
onClick 函数施行到位后,inner.click() 语句才退栈,继而实行 jobs
的天职。

唯有四个 mutate 是由于 jobs 队列中,只好有1个 MutationObserver
任务,第二遍成立时,前七个 MutationObserver 职责未有试行,顾不再创设。

总结

上述所述是作者给大家介绍的JS内部事件机制之单线程原理,希望对我们有所援助,若是咱们有其它疑问请给小编留言,小编会及时回复大家的。在此也13分感激我们对台本之家网址的支撑!

你恐怕感兴趣的稿子:

  • 剖析JS单线程异步io回调的特色
  • 详细分析单线程JS执行难题
  • 深切浅析Node.js单线程模型
  • 知情javascript沙漏中的单线程
  • 您不可能不知道的Javascript知识点之”单线程事件驱动”的行使

相关文章