JavaScript中的异步代码如何工作
在本文中,我们将学习 JavaScript 中异步代码的工作方式。让我们了解与同步 JavaScript 相关的基本细节。
同步 JavaScript:
- 同步 JavaScript 意味着用户可以同步访问并按顺序使用数据。
- 在这种情况下,用户尝试访问在代码的不同部分(如不同的函数或方法)中可用的数据,这些部分彼此相关或相互依赖。
- 以后进先出(LIFO)结构遵循的调用栈的概念得以应用,其中每个任务的函数通过移除堆栈顶部的任何现有内容来执行。
示例: 通过以下代码,让我们理解同步 JavaScript 的概念。
JavaScript
<script>
let secondFunction = () => {
console.log("GeeksforGeeks....");
console.log("Second Function execution is completed.....");
}
let firstFunction = () => {
console.log("First function Execution Starts.....");
secondFunction();
console.log("First Function execution ends here.....");
}
firstFunction();
</script>
输出:
First function Execution Starts.....
GeeksforGeeks....
Second Function execution is completed.....
First Function execution ends here.....
上述同步代码的工作原理通过以下调用堆栈的图示表示来解释。
- 每个元素都从栈的顶部移除,并在移除后在浏览器的控制台上打印。
- 这就是同步代码实际工作的方式,当不同的函数被调用时,它们各自的数据也被执行。
现在,我们已经了解了与同步JavaScript相关的细节,接下来我们将了解什么是异步JavaScript以及它在执行时的工作方式。
异步JavaScript:
- 异步JavaScript简单地意味着用户将以更快的方式接收数据。
- 当用户尝试从API(应用程序编程接口)资源中获取数据或尝试收集来自API的响应时,通常会发生这种情况。
- 为了处理异步数据,我们使用promise或回调函数,这有助于用户轻松地从API中获取响应或数据。
- 在了解了调用堆栈的基础知识之后,还存在一些更技术性的概念,例如事件循环、Web API和消息队列。
- 所有这些都与JavaScript引擎无关,实际上与浏览器的JavaScript运行时环境相关。
- 每当同步方法或DOM事件(例如setTimeout或promise或回调函数)出现时,它们会被执行到Web API中,并在计时器完成后被推送到消息队列中,然后事件循环进一步将该消息推送到调用堆栈中以执行。
- 事件循环所执行的任务基本上是确定堆栈是否为空。如果堆栈为空,则该特定事件循环从消息队列中获取数据以便在调用堆栈中执行。
示例1: 以下是一些示例,我们将使用promise、回调函数或DOM事件来展示JavaScript代码的异步性质。
JavaScript
<script>
console.log("Program Starts......");
setTimeout(() => {
console.log("setTimeout execution....");
}, 0);
new Promise((resolve, reject) => {
resolve("Promise resolved.....");
})
.then((res) => console.log(res))
.catch((error) => console.log(error));
console.log("Program Ends.....");
</script>
输出:
Program Starts......
Program Ends.....
Promise resolved.....
setTimeout execution....
示例2:
JavaScript
<script>
console.log("Program Starts......");
setTimeout(() => {
console.log("setTimeout 1 execution....");
}, 0);
setTimeout(() => {
console.log("setTimeout 2 execution....");
}, 0);
new Promise((resolve, reject) => {
resolve("Promise 1 resolved.....");
}).then((res) => console.log(res))
.catch((error) => console.log(error));
new Promise((resolve, reject) => {
resolve("Promise 2 resolved.....");
}).then((res) => console.log(res))
.catch((error) => console.log(error));
console.log("Program Ends.....");
</script>
输出:
Program Starts......
Program Ends.....
Promise 1 resolved.....
Promise 2 resolved.....
setTimeout 1 execution....
setTimeout 2 execution....