为什么有些JavaScript开发人员使用setTimeout一毫秒

Why are some JavaScript developers using setTimeout for one millisecond?

本文关键字:setTimeout 一毫 JavaScript 开发 为什么      更新时间:2023-09-26

我在使用jQuery插件表分类器时遇到问题,不能两次调用触发器。

例如,这不起作用:

this._$table.trigger('update');
this._$table.trigger('sorton', [[[1,1]]]);

但这是有效的:

this._$table.trigger('update');
setTimeout($.proxy(function() {
    this._$table.trigger('sorton', [[[1,1]]]);
}, this), 1);

然后我发现问题出现在触发器"更新"中,它调用了带有正文的方法:

function () {
    var me = this;
    setTimeout(function () {
        // rebuild parsers.
        me.config.parsers = buildParserCache(
        me, $headers);
        // rebuild the cache map
        cache = buildCache(me);
    }, 1);
}

为什么表分类器开发人员使用1毫秒的setTimeout

简称:函数执行排队

这是你问题的简短答案。具有0或1毫秒的CCD_ 2用于函数执行排队。继续阅读,了解原因和方法。

Javascript具有单线程执行

Javascript引擎是一个单线程进程。因此,每当开发人员希望将某些函数的执行推迟到当前刚执行的函数之后执行时,就会使用setTimeout来对下一个函数进行排队。。。它与事件没有任何直接关系,尽管函数可能是事件处理程序。此公式中唯一的事件是setTimeout创建的超时事件。

这是两个函数的一个例子,其中第一个函数在执行期间将第二个函数排在它之后执行

function first()
{
    // does whatever it needs to
    // something else needs to be executed right afterwards
    setTimeout(second, 1);
    // do some final processing and exit
    return;
}
function second()
{
    // whatever needs to be done
}

因此,对于javascript引擎线程,执行队列如下所示:

first()
second()

请注意,这与函数调用堆栈无关。

为什么是1ms

1ms是一个非常短的时间,它(几乎)确保了您的第二个函数将在第一个函数返回后立即执行。您有时甚至会看到0ms,它实际上是在第一个函数返回之后立即执行的。

另一方面,如果使用更长的时间,即100ms,这可能会导致在此期间执行不同的功能,并可能对整个UI过程产生不希望的影响。

为什么首先要排队

如今,浏览器通过观察长时间运行的功能,防止客户端功能挂起当前浏览器会话。如果某个特定的函数运行足够长的时间,浏览器Javascript执行引擎会暂停它,并询问用户是终止它(终止它)还是等待它完成。

当您确实有一个长时间运行的函数时,这通常是不希望的效果。例如,假设您有一个函数,它必须循环处理大量项目,在处理过程中处理每个项目。您绝对不希望用户因为需要执行循环而终止进程。

在这种情况下,解决方案是什么?在这种情况下,与其让一个函数带有循环并执行它,不如让循环(排队)函数对处理每个项目的函数调用进行排队。这只是此类功能的一个外部框架。

function queueItems(items) {
    for(var i = 0; i < items.length, i++)
    {
        setTimeout((function(item) {
            return function() {
                processItem(item);
            };
        })(items[i]), 0);
    }
}
function processItem(item) {
    // process individual item
}

这样可以防止函数运行时间过长,并且在每次执行函数后,控件都会返回到Javascript引擎,重置其函数挂起计时器。但要注意,当您的功能正在执行时,您的UI可能会没有响应,或者最多是不可预测的。最好在函数之间留出一定的时间间隔,以便UI在需要时保持响应。

这是一个老破解。如果一个事件需要在另一个事件之后触发,您可以使用具有1ms的setTimeout来确保该事件在另一事件之后触发。

我认为,由于trigger('update')内部有一个setTimeout,因此只有设置另一个setTimeout,才能实现所需的语句执行顺序。如果您不通过setTimeout调用'sorton',它将在'update'之前执行。

另一方面,我猜'update'使用setTimeout是为了防止"更新"在执行可能需要很长时间时成为阻塞函数。