与异步 JavaScript 同步
介绍
如果您是 JavaScript 开发人员,您可能听说过 JavaScript 是一种单线程、非阻塞、同步、并发的编程语言,具有很大的灵活性。
尽管确实如此,但 JavaScript 代码是异步执行的,这使程序能够处理调用堆栈中的耗时任务,并且仍然可以响应浏览器上的其他事件。
这些潜在的耗时任务可能是:
拿来: 它是一个 API,允许程序使用 HTTP 请求从外部获取资源。
设置超时: setTimeout() 它设置一个计时器,该计时器执行一个功能或一旦计时器用完。
地理位置 API: 它允许用户自愿向应用程序提供访问其地理位置到 Web 应用程序的权限。
什么是异步 JavaScript?
因此,本质上,异步 JavaScript 意味着一个程序可以一起运行多个任务,而无需等待其他任务完成并冻结程序。
让我们通过一个例子更好地理解异步代码:
你认为这段代码的结果是什么?
没有得到正确答案的布朗尼积分。代码按预期运行。
现在让我们添加一个异步函数,看看它如何改变代码的执行。
拍一张。你认为这段代码的输出会是什么?
如果你猜对了,赞一个。
如您所见,包含在 setTimeOut 中的函数在其余代码执行后执行。
这是因为在调用 setTimeOut 时,JS 引擎会创建一个新的函数执行上下文并将其添加到调用堆栈中,该调用堆栈在时间到期后运行,在本例中为 2000 毫秒(或 2 秒)。
这是最基本的异步代码示例。
重要的是要记住,JavaScript 仍然是一种单线程编程语言,但借助事件循环、调用堆栈和 Web API 等浏览器功能实现了异步
为了更好地理解异步,我们将不得不仔细研究调用堆栈和事件循环
调用堆栈
堆栈是计算机科学中的一种基本数据结构,它遵循 LIFO(后进先出)结构。调用堆栈只是一种跟踪函数调用的机制。
当 JavaScript 代码被执行时,首先发生的是 全局执行上下文 被建造。
接下来,每当调用一个函数时,JS 引擎都会创建一个唯一的 函数执行上下文 ,它位于调用堆栈的顶部。此外,如果它是一个调用函数,并且有一个回调函数,那么 JavaScript 引擎会创建另一个函数执行上下文并将其放置在调用堆栈的顶部。
一旦函数执行完毕,它就会从堆栈中弹出,调用堆栈开始执行下一个函数执行上下文。这本质上就是调用堆栈的工作方式。
然而,调用堆栈只是一个更大的难题的一小部分,即事件循环。
事件循环
因此,总结一下我们到目前为止所学到的知识,JavaScript 是一种单线程编程语言,这意味着它从顶部开始执行脚本并一直工作到底部,沿线程推送和弹出函数执行上下文 (FEC)方式,从而异步执行多个功能。
通常,在同步运行时执行需要很长时间的函数会冻结程序,尽管是暂时的。
现在在我们继续理解事件循环之前,我们需要理解另一个难题,队列。
在计算机科学中,队列是一种两端开放的线性数据结构,即它遵循先进先出 (FIFO) 顺序,与堆栈相反。
JavaScript 运行时使用一个任务队列,其中包含必须处理的任务列表,每个任务都有一个关联函数,需要调用该函数才能完成任务。
本质上,事件循环是 JavaScript 运行时将任务从队列中拉出并将其放入调用堆栈的过程,只要堆栈为空。尽管这是对一个相当复杂的概念的过度简化,但它本质上是异步代码的执行方式。
这就是我们如何得到 JavaScript 是多线程的错觉,尽管它的核心是并且永远是单线程的。
所以现在让我们使用我们在文章前面使用的 setTimeOut 函数示例来连接这些点。
当代码开始运行时,它会执行第 3 行。直到现在都没有意外。
在下一步中,当它到达行号时。 5、JS运行时注意到这个函数有一个2秒的定时器,这意味着它不能立即运行。因此,它立即将其放入任务队列并继续执行下一行代码。
正如预期的那样,“一”、“三”和“四”会立即记录在控制台中,2 秒后,事件循环将回调函数从队列中取出并放入堆栈,“二”得到登录控制台。
这本质上就是事件循环的工作方式,反过来,异步 JavaScript 也能工作。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明
本文链接:https://www.qanswer.top/39164/33432511
标签:异步,同步,函数,JavaScript,调用,堆栈,执行 From: https://www.cnblogs.com/amboke/p/16727536.html