js执行机制(同步,异步)

简介: js执行机制(同步,异步)

1.前言


javascript 是一门(动态、弱类型、面向对象)单线程,解释性(脚本)语言。执行过程是自上而下,一行一行的。ps:要明确一个观念,所谓的js、primise、$nextTick、axios、同步异步、微任务宏任务……一切的一切只不过都只是个工具而已,他的出现只为解决问题,他们的存在也是为解决问题才存在。


本篇文章尽量不涉及专业名词,尽可能用通俗易懂的词语,解释JavaScript的运行机制,及阐述同步任务和异步任务。注:异步任务又细分为微任务和宏任务。  

2 生活举例


现在我就是JavaScript。我妈让我回家吃饭,吃完饭去洗漱,然后睡觉。我按部就班的吃饭、洗漱、睡觉,很简单么,按流程顺序走就完事了。


第二天,我去银行上班,我是窗口的业务员,别人来办业务,就会排队,我按照排队的人的顺序,每次给一个人办业务,有时候,有那么个人磨磨唧唧,这事那事的耽误我不少时间,后面排队的人很着急,可是没办法啊,倒霉白。可惜了,整个银行就我这一个窗口。看看隔壁的银行,窗口老多了,不用等半天,而且遇到磨磨唧唧的人也会好很多。


第三天,我想到一个好办法! 有一个办业务磨磨唧唧的人,我对她说,你先去天津教育大厦买一瓶水,然后再到我这里来。于是,我把他打发走了,虽然我最终还是要处理这个磨磨唧唧的人,可是剩下的人就可以立刻帮他们办业务了,或许等那个墨迹的人回来,我这里就很空闲,这样就不会耽搁时间了,妙啊。

3 由浅:


在深入之前,先了解一下概念:


1.单线程和多线程


单线程:我只有一只手。


多线程:我是哪吒,能同时拿手机,敲代码,吃冰柜。


2.进程和线程的概念和区别:百度。


3.并发及高并发?


你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。最惨的是来了电话我不接,吃完饭才接。


无论上一个开始执行的任务是否完成,当前任务都可以开始执行并发的关键是你有处理多个任务的能力,不一定要同时


其实,与之相反的是,你只能等待上一个任务结束,才能执行下一个任务。


4.并行及高并行?


你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。


4.1 并行的关键是你有同时处理多个任务的能力。


4.2 最关键的点就是:是否是『同时』。


总结:js是通过队列机制,事件机制实现并发的。而所谓的同步异步也是基于js的运行机制,才产生的。


5.宏任务和微任务:他俩执行的时候不是放在一个执行队列里,先执行微任务队列,在执行宏任务。所以:同步任务 > 异步任务(微任务)>异步任务(宏任务)

4 javascript事件循环


  • 同步任务
  • 异步任务


20210615004053125.jpg

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

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

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

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

总结:刚开始正常是一行一行执行代码。遇到异步任务,就把他扔到异步处理程序里面。先执行同步任务,同步执行完毕后去事件队列(eventloop)里面去执行异步程序,主线程执行完异步任务后,再去任务队列看看还有没有,有的话,再执行,再回去看有没有…一直循环,直到所有代码执行完毕。

5 举例异步之宏任务: setTimeout


他是一个经典宏任务,举例一下他的使用,来验证js的运行机制。请问这个定时器里面的函数会在3秒之后调用吗?


答案:不可能。首先定时器会被扔到任务队列中,接着执行同步任务for循环,结果掉进坑了,出不来了,3秒后,定时器说:‘哎!我到点了,该执行我里面的fn()函数了’,结果js说:‘等……等一下…呃!’ 这个定时器等了远远超过3秒,具体啥时候就不一定了。第二个,定时器如果不写延时时间的话,最早可得的空闲时间执行,而浏览器默认大概4毫秒。

setTimeout(() => {
    fn()
},3000)
for(let  i = 0 ; i < 一万万亿次; i++)   //随便举例,切勿当真,不然崩溃别找我。

5.1宏任务有哪些?

setTimeout

setInterval

script

I/O

UI交互事件

postMessage

MessageChannel

setImmediate(Nodejs环境)

6 异步之微任务:Promise与process.nextTick(callback)


我理解的promise是一个为了解决回调地狱而设计出的一个对象,里面有一些方法。他本身是同步的(就一对象而已),只不过里面的then是异步的,但then的目的是同步(或者更像同步,毕竟同步最容易理解),以及基于promise的async,await


微任务包含:

Promise.then
Object.observe
MutaionObserve
process.nextTick(Node.js环境)

7.好了,试试手吧


image.png

 输出 1 2 4 5 3 6
<script>
   const promise = new Promise((resolve,reject)=>{
     console.log(1);
     resolve(5)  可以看成是监听then(val)做完了的状态,其实可以把它看成是同步的
     console.log(2);
   }).then((val)=>{
     console.log(val);
   })
   console.log(4);
   promise.then(()=>{
     console.log(3);
   })
   setTimeout(()=>{
     console.log(6);
   },0)
  </script>

8.入深

下面这个包含所有任务,且局中局套中套。我会详细解释,为什么这么输出。

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')
    })
})

20210615234026290.png

额,还有好多想法写不出来,火候不到,时间不到,等以后再来补上吧。

相关文章
|
2月前
|
存储 JavaScript 前端开发
深入理解JavaScript中的事件循环(Event Loop):机制与实现
【10月更文挑战第12天】深入理解JavaScript中的事件循环(Event Loop):机制与实现
82 3
|
19天前
|
JSON 前端开发 JavaScript
在 JavaScript 中,如何使用 Promise 处理异步操作?
通过以上方式,可以使用Promise来有效地处理各种异步操作,使异步代码更加清晰、易读和易于维护,避免了回调地狱的问题,提高了代码的质量和可维护性。
|
19天前
|
JavaScript 安全 中间件
深入浅出Node.js中间件机制
【10月更文挑战第36天】在探索Node.js的奥秘之旅中,中间件的概念如同魔法一般,它让复杂的请求处理变得优雅而高效。本文将带你领略这一机制的魅力,从概念到实践,一步步揭示如何利用中间件简化和增强你的应用。
|
1月前
|
消息中间件 JavaScript 中间件
深入浅出Node.js中间件机制
【10月更文挑战第24天】在Node.js的世界里,中间件如同厨房中的调料,为后端服务增添风味。本文将带你走进Node.js的中间件机制,从基础概念到实际应用,一探究竟。通过生动的比喻和直观的代码示例,我们将一起解锁中间件的奥秘,让你轻松成为后端料理高手。
28 1
|
2月前
|
前端开发 JavaScript 开发者
JS 异步解决方案的发展历程以及优缺点
本文介绍了JS异步解决方案的发展历程,从回调函数到Promise,再到Async/Await,每种方案的优缺点及应用场景,帮助开发者更好地理解和选择合适的异步处理方式。
|
2月前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
32 0
|
2月前
|
JavaScript 安全 中间件
深入浅出Node.js中间件机制
【10月更文挑战第4天】在探索Node.js的海洋中,中间件机制犹如一座灯塔,为开发者指引方向。本文将带你一探究竟,从浅入深地理解这一核心概念。我们将通过生动的比喻和实际代码示例,揭示中间件如何在请求和响应之间搭建桥梁,实现功能的扩展与定制。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
50 0
|
JavaScript 前端开发 C++
javascript中的执行环境和作用域详解
首先,我们要知道执行环境和作用域是两个完全不同的概念 函数的每次调用都有与之紧密相关的作用域和执行环境;从根本上来说,作用域是基于函数的,而执行环境是基于对象的(例如:全局执行环境即window对象);换句话说,作用域涉及到被调用函数中的变量访问,且不同的调用场景是不一样的;执行环境始终是this.
4449 0