这篇文章主要介绍同步JavaScript是如何工作的,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
虽然单线程简化了编程代码,因为你不必太担心并发引出的问题,这也意味着你将在阻塞主线程的情况下执行长时间的操作,如网络请求。
想象一下从API请求一些数据,根据具体的情况,服务器需要一些时间来处理请求,同时阻塞主线程,使网页长时间处于无响应的状态。
这就是引入异步JavaScript的原因。使用异步JavaScript(如回调函数,承诺,异步/等待),可以不用阻塞主线程的情况下长时间执行网络请求:)
可能你知道不知道异步JavsScript是如何工作,并不要紧,但知道它是如何工作,对JavaScript异步更深入的了解是有帮助的。
所以不在啰嗦了,我们开始吧:)
同步JavaScript是如何工作的?
在深入研究异步<代码> JavaScript代码>之前,让我们首先了解同步JavaScript <代码> 代码>代码如何在<代码> JavaScript代码>引擎中执行。例如:
const第二=()=比;{ console.log(& # 39;你好! & # 39;); } const第一=()=比;{ console.log(& # 39;嗨! & # 39;); 第二个(); console.log(& # 39;结束# 39;); } 第();
要理解上述代码如何在JavaScript引擎中执行,我们必须理解执行上下文和调用堆栈(也称为执行堆栈)的概念。
函数代码在函数执行上下文中执行,全局代码在全局执行上下文中执行。每个函数都有自己的执行上下文。
调用栈
调用堆栈顾名思义是一个具有后进先出(后进先出)结构的堆栈,用于存储在代码执行期间创建的所有执行上下文。
JavaScript只有一个调用栈,因为它是一种单线程编程语言。调用堆栈具有后进先出结构,这意味着项目只能从堆栈顶部添加或删除。
让我们回到上面的代码片段,并尝试理解代码如何在JavaScript引擎中执行。
const第二=()=比;{ console.log(& # 39;你好! & # 39;); } const第一=()=比;{ console.log(& # 39;嗨! & # 39;); 第二个(); console.log(& # 39;结束# 39;); } 第();
这里发生了什么?
当执行此代码时,将创建一个全局执行上下文(主要由()表示)并将其推到调用堆栈的顶部。当遇到对第()的调用时,它会被推送到堆栈的顶部。
接下来,console.log(& # 39;嗨! & # 39;)被推送到堆栈的顶部,当它完成时,它会从堆栈中弹出。之后,我们调用第二个(),因此第二()函数被推到堆栈的顶部。
console.log(& # 39;你好! & # 39;)被推送到堆栈顶部,并在完成时弹出堆栈,接着()函数结束,因此它从堆栈中弹出。
控制台。日志(“结束”)被推到堆栈的顶部,并在完成时删除。之后,第一个()函数完成,因此从堆栈中删除它。
程序在这一点上完成了它的执行,所以全局执行上下文(main())从堆栈中弹出。
异步JavaScript是如何工作的?
现在我们已经对调用堆栈和同步JavaScript的工作原理有了基本的了解,让我们回到异步JavaScript。
阻塞是什么?
让我们假设我们正在以同步的方式进行图像处理或网络请求。例如:
const processImage=(图像)=比;{/* * *做一些操作> const networkRequest=()=比;{ setTimeout(()=比;{ console.log(& # 39;异步代码# 39;); }, 2000); }; console.log(& # 39;你好& # 39;); networkRequest ();
这里我使用了setTimeout方法来模拟网络请求。请记住setTimeout不是JavaScript引擎的一部分,它是web api(在浏览器中)和C/c++ api(在node . js中)的一部分。
为了理解这段代码是如何执行的,我们必须理解更多的概念,比如事件轮询和回调队列(或消息队列)。
事件轮询,web api和消息队列不是JavaScript引擎的一部分,而是浏览器的JavaScript运行时环境或Nodejs JavaScript运行时环境的一部分(对于Nodejs)。在Nodejs中,web api被C/c++ api所替代。
现在让我们回到上面的代码,看看它是如何异步执行的。
const networkRequest=()=比;{ setTimeout(()=比;{ console.log(& # 39;异步代码# 39;); }, 2000); }; console.log(& # 39;你好& # 39;); networkRequest (); console.log(& # 39;结束# 39;);