Js - 运行机制 (Even Loop)

Javascript 的单线程 - 引用思否的说法:

JavaScript的一个语言特性(也是这门语言的核心)就是单线程。什么是单线程呢?简单地说就是同一时间只能做一件事,当有多个任务时,只能按照一个顺序一个完成了再执行下一个。

那为什么JS是单线程的呢?

  • JS最初被设计用在浏览器中,作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM
  • 如果浏览器中的JS是多线程的,会带来很复杂的同步问题
  • 比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
  • 所以为了避免复杂性,JavaScript从诞生起就是单线程

为了提高CPU的利用率,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以这个标准并没有改变JavaScript单线程的本质;

任务队列 Task queue

在Javascript中,所有的任务分为两类:同步任务和异步任务

同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

简要说明:在这里说到了   ‘主线程’   和    ‘任务队列’ ,个人简单理解: 主线程就是 Js 执行的线程 , 任务队列是异步任务暂时存放的一个事件队列;

在Js执行中,同步任务和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入 Event Table 并注册函数。

当指定的事情完成时,Event Table  会将这个函数移入 Event Queue (事件队列)。

主线程内的任务执行完毕为空,会去 Event Queue 读取对应的函数,进入主线程执行。

上述过程会不断重复,也就是我们常说的 Event Loop(事件循环)。

通过上边的描述,我们来看一张图更加清晰的了解  Event Loop (事件循环) 机制

接下来我们看一个例子:

        setTimeout(function(){
console.log('1')
}); new Promise(function(resolve){
console.log('2');
resolve();
}).then(function(){
console.log('3')
}); console.log('4');

首先setTimeout 是异步进入 事件队列,然后 promise 的 then 也是异步 进入事件队列 ,

那么按照我们上边说的Js执行机制,先走主线程的同步任务,打印2 ,然后4,紧跟着执行异步任务,也就是任务队列打印1,随后是 3 , 所以结果应该是 2,4,1,3,  事实真的是这样子嘛 ?  接着往下看 :

Js 中的宏任务和微任务 - 略记一下

macro-task(宏任务) :包括整体代码  script,setTimeout,setInterval

micro-task(微任务)  : Promise,process.nextTick

process.nextTick(callback)类似node.js版的"setTimeout",在事件循环的下一次循环中调用 callback 回调函数)

我们上边的  setTimeout  放到了 event queue 事件队列里 , promise 的 then 函数 也被放到了 event queue 事件队列里,然而杯具来了,这两个 queue 并不是一个队列;

在 Js  Event Loop 机制中

Promise 执行器中的代码会被主线程同步调用,但是 promise 的回调函数是基于微任务的

宏任务的优先级高于微任务

每一个宏任务执行完毕都必须将当前的微任务队列清空

emmmm~~

现在我们回到上边的例子中,因为 settimeout 是宏任务,虽然先执行的它,但是他被放到了宏任务的 event queue 里面,然后代码继续往下检查看有没有微任务,检测到 Promise 的 then 函数把它放入了微任务队列。等到主线进程的所有代码执行结束后。先从微任务

queue 里拿回调函数,然后微任务queue空了后再从宏任务的queue拿函数。

所以正确的执行结果当然是:2,4,3,1 ;

由此延申一下  事循环-宏任务-微任务  (Event Queue - Macro - Micro )关系图:

最后出一个小试题,看看大家是否真的理解到了 Js 的运行机制

试题借鉴  ssssyoki   答案及分析请前往 ssssyoki 博客。

console.log('1');

setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
}) setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})

Js 运行机制 event loop的更多相关文章

  1. 再次聊一聊promise settimeout asycn awiat执行顺序---js执行机制 EVENT LOOP

    首先js是单线程 分为同步和异步,异步又分为(macrotask 宏任务 和 microtask微任务 ), 这图还是很清晰嘛,再来一张 总结一下,就是遇到同步先执行同步,异步的丢到一边依次排队,先排 ...

  2. JavaScript 运行机制 (Event Loop)

    单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务.如果前一个任务耗时很长,后一个任务就不得不一直等着. 所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步 ...

  3. 从浏览器多进程到JS单线程,JS运行机制的一次系统梳理

    前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正. ----------超长文+多图预警,需要花费不少时间.---------- 如果看完本文后,还对进程线程傻傻分不清,不清楚浏 ...

  4. js 运行机制

    <script> console.log(1) setTimeout(function(){ console.log(3) },0) console.log(2) </script& ...

  5. 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理

    前言 来源:https://dailc.github.io/2018/01/21/js_singlethread_eventloop.html 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会 ...

  6. 如何通过setTimeout理解JS运行机制详解

    setTimeout()函数:用来指定某个函数或某段代码在多少毫秒之后执行.它返回一个整数,表示定时器timer的编号,可以用来取消该定时器. 例子 ? 1 2 3 4 5 console.log(1 ...

  7. Js 运行机制 (重点!!)

    一.引子 本文介绍JavaScript运行机制,这一部分比较抽象,我们先从一道面试题入手: 这一题看似很简单,但如果你不了解JavaScript运行机制,很容易就答错了.题目的答案是依次输出1 2 3 ...

  8. js 运行机制简单了解

    一.如何理解 JS 的单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. JavaScrip ...

  9. 面试 09-02.js运行机制:异步和单线程

    09-02.js运行机制:异步和单线程 #前言 面试时,关于同步和异步,可能会问以下问题: 同步和异步的区别是什么?分别举一个同步和异步的例子 一个关于 setTimeout 的笔试题 前端使用异步的 ...

随机推荐

  1. 最全的Spring AOP

    1.什么是AOP? AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, ...

  2. Tips——RN canvas缩放处理

    一.关于canvas缩放 canvas图像缩放处理有两种思路: ctx.scale(),对整个canvas进行重绘,会导致每次缩放都重新加载,影响体验效果 在canvas外包层view,直接对外层的v ...

  3. 学web前端一定要这样学,不然学完找不到工作哭都来不及!

    因为工作原因,经常关注有关互联网行业的最新动态.这不,刚送走了高考,又迎来了每年的毕业季,看到好多人都说今年的前端工作不好找,很多童鞋简历投了一大堆,也没有回应,发现连实习的机会都没有,好不容易去面试 ...

  4. css类选择器类名覆盖优先级

    code <style> .a{ background: red; } .b{ background: yellow; } </style> <div class=&qu ...

  5. ida不错的插件记录

    IDASkins 地址 https://github.com/zyantific/IDASkins 作用 ida黑色皮肤插件 IDAFuzzy 地址 https://github.com/Ga-ryo ...

  6. web 应用响应乱码问题

    非西欧语系乱码原因 在没有设置任何内容类型或编码之前,HttpServletResponse使用的字符编码默认是ISO-8859-1.也就是说,如果直接输出中文,在浏览器上就会看到乱码. 有两种方式可 ...

  7. 浅谈java动态代理

  8. 软工读书笔记 week 7 ——《构建之法》

    总时长近两周的结对项目终于算是结束了,马上要重新开启团队项目.于是这几天决定对<构建之法>一书中与团队项目及需求分析有关的章节进行重点阅读,希望能够从中得到启发,并运用到接下来的团队项目中 ...

  9. 【日常记录】【unity3d】 2D跳跃过快导致角色某帧陷入地面

    如果角色运动过快会导致嵌入地面再反弹出来 : 可以使用更高质量的检测方式 "Continuous" :就可以解决这个问题

  10. Win10自动重启原因怎么查Windows10无故自动重启

    电脑偶尔自动重启,可能很少用户会在意,若电脑经常无故重启,那么应该怎么办,怎么查找电脑无故自动重启原因呢?下面就以Windows10系统自动重启为例,来查查WIN10无故重启是什么原因导致.百度经验: ...