javascript中如何进行时间切片

How does time slicing happen in javascript?

本文关键字:时间 切片 何进行 javascript      更新时间:2023-09-26

或ecmascript,但我想知道它实际上是如何发生的,是否更多地取决于具体的实现。

javascript在技术上是单线程的。

但如果我做一些类似的事情

$myDIv.animate({
    height:"100px"
});

如果我做有什么区别吗

A。

$myDIv.animate({
    height:"100px"
}, null, my_cpu_heavy_function);

或B.

$myDIv.animate({
    height:"100px"
});
my_cpu_heavy_function();

因为在第二个版本中,动画将与cpu繁重的功能争夺处理时间,因此动画的外观会受到影响,对吧?

那么,Javascript是在同步代码块结束时停止执行,还是在任何随机点切断一个块,以允许处理另一个异步运行的块?

javascript中没有时间切片。Javascript是单线程的(除了我们不在这里讨论的网络工作者)。javascript执行的一个线程一直运行到它完成。

在第一个代码示例中,动画完成它的工作,当它完全完成时,它调用my_cpu_heavy_function

在第二个代码示例中,动画初始化自身,并为其第一个动画步骤设置计时器。然后它返回并进入下一行代码。动画才刚刚开始(并在未来设置了一个短时间的计时器来做更多的工作)——它还没有完成。然后,运行my_cpu_heavy_function,它占用整个javascript执行,直到它完成为止。my_cpu_heavy_function正在运行时,动画根本不会运行。完成后,动画集的计时器事件将启动,动画将继续运行。

动画可能"看起来"像时间切片,但实际上并非如此。jQuery动画在动画中移动一步,然后为将来的一小段时间设置计时器,然后返回系统。当计时器事件触发时,jQuery会执行动画中的下一步,依此类推。当计时器事件激发时,它会将计时器事件放入javascript事件队列。如果当前没有运行javascript,则会立即启动计时器回调。如果javascript当前正在运行,那么计时器事件只会出现在事件队列中,直到当前javascript线程结束。当该线程完成时,javascript会在事件队列中查看是否有任何事件在等待。如果存在,则调用事件回调。

因此,对于不同的javascript片段,实际上没有时间切片。想要运行的两段代码并没有像本机代码中的真实线程那样,分别给定一些CPU周期。在javascript中,一段代码一直运行到它完成,然后可以启动下一个事件。在基于javascript的动画中,可以通过做少量的工作,然后为未来的某个时间设置计时器并返回系统来模拟时间切片。一旦执行完毕,其他一些javascript就可以运行,但它也会一直运行到执行完毕。如果所有javascript都只做少量的工作,然后为下一项工作设置计时器,那么它们都可以合作,看起来就像是在分时间,但这只是因为它们之间的合作。如果出现像my_cpu_heavy_function这样的函数并占用CPU一段时间,那么在这段时间内没有其他函数运行。my_cpu_heavy_function运行时动画将停止。

浏览器中的一些操作是由浏览器中的本地代码执行的(如ajax调用、加载图像等)。这些异步任务可以在javascript运行时在后台进行,但在当前javascript执行线程完成并启动带有通知回调的新线程之前,它们不会通知javascript。

举个例子,假设我们有一个需要1秒加载的映像和一个需要5秒运行的CPU密集型函数。然后我们有了这个代码:

var img = new Image();
img.onload = function() {
    alert("image is loaded now");
}
img.src = "xxx.jpg";
longFunctionThatTakesFiveSecondsToRun();

当我们运行此代码时,即使在浏览器中内部加载映像只需要1秒,但只有在5秒钟后longFunctionThatTakesFiveSecondsToRun()运行完毕后,才会调用onload处理程序。它必须等到当前执行线程完成后才能处理onload事件。

如果您想了解更多关于javascript事件队列和异步操作的信息,请参阅以下相关答案:

JavaScript如何在后台处理AJAX响应?

使用JavaScript事件处理的比赛条件?

JS事件处理程序是否可以中断另一个处理程序的执行?

我需要关注异步Javascript的竞争条件吗?

如果我做A或B 有什么区别吗

是的,这会有所不同。

第二个版本没有太多的处理时间。这更像是my_cpu_heavy_function一旦开始就会占用所有的处理时间,假设它是同步的。

换言之,同步代码一旦开始,它就不会结束,直到完成,而与可能计划运行的任何定时异步代码无关。异步代码将始终被强制等待同步代码完成。

因此,动画将开始并执行初始化,但随后my_cpu_heavy_function将立即开始,并阻止动画的其余部分,直到完成为止。