异步 JavaScript 代码如何在浏览器中执行?
与其他函数或操作并行运行的函数或操作在 JavaScript 中称为异步函数或操作。异步函数使用稍后执行的回调函数。让我们看一个例子来证明这一点:
Javascript
setTimeout(function greet() {
console.log("Welcome to GeeksforGeeks!");
}, 2000);
Javascript
setTimeout(function greet(){
console.log("Welcome to GeeksforGeeks!");
}, 2000);
console.log("Hi!");
在上面的例子中, setTimeout是一个异步函数,使用了回调函数greet的延迟 2000 毫秒。因此,计时器到期后,消息会打印在控制台中。现在,让我们看看上述操作是如何在浏览器的 JavaScript 引擎中执行的。
执行异步 JavaScript 的幕后:
JavaScript 代码由调用堆栈执行,由于调用堆栈不包含任何类似计时器的东西,我们不能延迟代码执行。因此,为了执行异步操作,我们使用浏览器的window全局对象中可用的 web API s etTimeout()的帮助。
有趣的是, setTimeout不是 JavaScript 的一部分,它是浏览器全局对象中可用的众多 Web API(例如: setTImeout 、DOM API、 fetch 、 LocalStorage 、控制台、位置等)之一。浏览器使 JavaScript 引擎能够通过这个全局对象访问这些 Web API。而且,因为window是一个全局对象,我们可以在没有window关键字的情况下访问 Web API。
要了解在浏览器中执行异步代码的幕后工作原理,让我们首先看一个异步代码的示例。
例子:
Javascript
setTimeout(function greet(){
console.log("Welcome to GeeksforGeeks!");
}, 2000);
console.log("Hi!");
这里setTimeout在 web API 环境中注册了回调函数greet并附加了一个时间为 2 秒的计时器。现在,所有 JavaScript 都由调用堆栈执行,JavaScript 引擎将首先创建一个全局执行上下文,并将执行最后一行并打印“Hi!”在控制台中。
执行完成后,全局执行上下文将从调用堆栈中删除。现在,在计时器到期后,为了打印问候消息,我们需要以某种方式将回调函数greet获取到调用堆栈以便执行。这是由 事件循环和回调队列。
定时器超时后,回调函数被放入回调队列中,事件循环的工作是检查调用堆栈是否为空,如果为空,则将回调队列中的回调函数推送到调用堆栈,回调函数得到从回调队列中删除。然后调用栈创建回调函数的执行上下文并执行它。
因此,代码的输出将是:
Hi!
Welcome to GeeksforGeeks!
延迟 2 秒后将显示第二行。这就是 JavaScript 中的异步操作如何在浏览器的后台执行。