Javascript方法起作用,但不起作用';行不通

Javascript方法起作用,但不起作用';行不通,javascript,Javascript,我甚至很难问这个问题,因为我不明白发生了什么 基本上,我有一个旋转加载器元素,它应该在javascript运行时显示。在javascript结束时,应该关闭加载程序,并显示一个模式,其中包含从数据库查询的数据。问题是加载程序从未显示。当查询在创建模式之前运行时,大约需要等待1-2秒 function includeConnectionJS() { if (!(typeof sforce === "object")) { var connectionJS = documen

我甚至很难问这个问题,因为我不明白发生了什么

基本上,我有一个旋转加载器元素,它应该在javascript运行时显示。在javascript结束时,应该关闭加载程序,并显示一个模式,其中包含从数据库查询的数据。问题是加载程序从未显示。当查询在创建模式之前运行时,大约需要等待1-2秒

function includeConnectionJS() {
    if (!(typeof sforce === "object")) {
        var connectionJS = document.createElement('script');
        var documentHead = document.getElementsByTagName('head')[0];

        connectionJS.src = '/soap/ajax/38.0/connection.js';
        connectionJS.setAttribute('onload', 'createLoader();createModal();');
        documentHead.appendChild(connectionJS);
    } else {
        createLoader();
        // Checks to see if the loader element exists. If it does not, create the element and than toggle it to display it.
        // If the element already exists, display the modal
        createModal();
        // Checks to see if the modal element exists, if it does not, create the element and than turn off the loader and display the modal.
        // If the element already exists, turn off the loader and display the modal
    }
}
我将console.logs放在方法中,可以清楚地看到方法正在被调用,if语句都在传递,元素的可见性在正确的时间更改为正确的值。一切似乎都暗示它应该工作,但元素从未实际显示

通过将对CreateModel的调用更改为如下所示,我可以使其显示:

setTimeout(function(){createModal()}, 100); // Most values for delay worked.
我不想创造一个人为的延迟只是为了显示效果

我主要关心的是CreateModel方法调用数据库。这些会导致javascript执行延迟(我同步调用它们,而不是异步调用它们)。我可以清楚地看到加载器显示在查询之前被设置为“block”,观察所有查询的调用和返回,并看到加载器的显示以正确的顺序变回“none”。更重要的是,如果我调用createLoader();方法直接从控制台执行,它可以工作


我只是不知道我缺少了什么。

通过同步Javascript调用,您正在阻止UI和事件循环中排队的其他函数。记住Javascript代码在单个线程中执行是很重要的。因此,没有代码可以并行执行,其他所有操作都必须等待当前任务完成。实际上,这意味着您希望您的函数尽快完成其工作,以便可以执行其他操作(UI更新、键盘/鼠标事件等、超时或异步回调等)。它们都必须等待,直到您通过完成当前代码块将控制权传递回引擎

setTimeout
之所以有效,是因为它将长时间运行的
createModal
函数添加到事件队列中,以便将来某个时候执行(即使设置为0ms,也不能保证立即执行,它只是在第一次机会时说,可以在0ms之后的某个时间执行。如果您有一个长时间运行的函数,实际上可能需要10秒)。这样做可以使调用函数快速完成,UI现在可以应用任何更新。现在,当javascript引擎准备好运行进一步的代码时,它将查找事件循环中记录的下一个代码块。这次,当它运行
createModal
时,它将再次阻止对UI的更新,等等,并使用鼠标和键盘d事件等,但现在UI已经有机会更新,您将拥有您的微调器


因此,选择是:要么在函数中使用异步调用以使其快速完成,要么在无法完成的情况下,在UI更新后继续使用
setTimeout()
将长时间运行的任务排队。

您描述的所有内容,从正确的顺序到
setTimeout
“修复”这个问题听起来像是
createModal()
过早地关闭了加载程序。我们无法在不查看其余代码的情况下为您提供帮助。暗中猜测:如果您想让JS在B发生后执行A(),您需要传递
函数(){A();}
,而不是
A();
@ChrisG不,Javascript的本质是阻止对UI的更新,直到执行的代码完全完成。而且Javascript在单个线程中顺序执行,因此
a
将始终在
B
之后执行
B();a();
a
B
完成之前无法启动