【问题标题】:Calling a function asynchronously?异步调用函数?
【发布时间】:2026-02-02 00:15:02
【问题描述】:

我有一个昂贵的函数,createNewWindow()。我想在调用方法时显示进度指示器,然后在函数完成时隐藏该指示器。虽然我尝试过的所有方法,但在方法完成之前我看不到进度指示器,所以我试图异步调用该方法(并且失败)。

我试过这个:

$( "#submit" ).click( function () {
    $("#progress").show();
    $.Deferred(createNewWindow());
} );

createNewWindow 的最后一行是 $("#progress").show()。没用。在此之前我尝试过:

$( "#submit" ).click( function () {
    $("#progress").show();
    setTimeout(createNewWindow(), 0);
} );

同样的效果。

这样做的正确方法是什么?

我看到了一些其他 SO 帖子,例如 this,它们描述了使用 setInterval 或 setTimeout,但我无法让它们像我预期的那样工作。

【问题讨论】:

  • 以异步方式调用同步函数并不能做到这一点。它仍然会阻止浏览器,你最好的选择是旋转的图像。

标签: javascript jquery asynchronous


【解决方案1】:

这是一个常见的错误。问题就在这里:

setTimeout(createNewWindow(), 0);

这将立即调用createNewWindow 并将结果(可能是无效的)传递给setTimeout。这不是你想要的,你想将 函数 createNewWindow 传递给 setTimeout 以便它在以后调用它:

setTimeout(createNewWindow, 0);

注意缺少的括号。您将createNewWindow(它是一个函数)的值传递给setTimeout,而不是调用它并传递它的返回值。

这应该会立即显示进度条。但是,如果 createNewWindow 是一个消耗大量资源的非常昂贵的函数,它仍然会减慢您的网页速度,因为您的所有 JavaScript 代码都在同一个线程中运行。在这种情况下,您可能需要考虑using a Worker

【讨论】:

  • 这是一个很好的收获,谢谢!不幸的是,它仍然没有得到正确显示的进展......可能是因为正如你在同一个线程中提到的那样。但是,我只看到将 URL 指向 js 文件的工作人员示例?有没有办法用函数创建一个新的 Worker?也许就像new Worker(createNewWindow) 一样简单?