【问题标题】:Why there is some delay caused by a JavaScript function that isn't supposed to run immediately? [duplicate]为什么不应该立即运行的 JavaScript 函数会导致一些延迟? [复制]
【发布时间】:2019-05-16 04:40:11
【问题描述】:

我有两个函数,showhidegetSourceCode。我希望showhide 在提交后立即执行(隐藏对话框),但getSourceCode 很长,所以我让它稍后执行。但是,在我点击提交和showhide 生效之间仍然会出现一些延迟。当我删除getSourceCode时,对话框可以立即消失,但只要有getSourceCode,它总是延迟,即使我setTimeout它。

document.querySelector("[type=submit]").onclick = function (event) {

    showhide('dialogBox');

    if (options[0].checked) {
          setTimeout(getSourceCode(),10000);          
    }
}

function getSourceCode() {

    var htmlastext = ajax("something.aspx");

    function HTML(text) {

        this.fullCode = (new DOMParser()).parseFromString(text, "text/html");
        this.scripts = this.fullCode.querySelectorAll("script[src]");
        this.style = this.fullCode.querySelector("link[rel=stylesheet]");
        this.images = this.fullCode.querySelectorAll("img");

        this.replaceContent = function (content, element, tag) {
            var newElement = this.fullCode.createElement(tag);
            newElement.innerHTML = content;
            element.parentNode.replaceChild(newElement, element);
        }

        this.modify = function () {

            var externalContent;
            var serverpath = window.location.origin;

            for (var i = 0; i < this.scripts.length; i++) {
                externalContent = ajax(this.scripts[i].src.slice(serverpath.length));
                this.replaceContent(externalContent, this.scripts[i], "script");
            }

            externalContent = ajax(this.style.href.slice(serverpath.length));
            this.replaceContent(externalContent, this.style, "style");


            var removeTagList = [
                this.fullCode.getElementById("logout"),
                this.fullCode.getElementById("saveHTML"),
                this.fullCode.getElementById("dialogOverlay"),
                this.fullCode.querySelectorAll("script")[4],
                this.fullCode.querySelector("link")
            ];

            for (i=0; i<removeTagList.length; i++) {
                removeTagList[i].parentNode.removeChild(removeTagList[i]);
            }
        }
    }

    var htmlDoc = new HTML(htmlastext);
    var html = htmlDoc.fullCode;
    htmlDoc.modify();
    htmlastext = (new XMLSerializer()).serializeToString(html);

    var txtarea = document.createElement("textarea");
    txtarea.innerHTML = htmlastext;
    htmlastext = txtarea.value;
    document.getElementById("encodedSourceCode").value = btoa(htmlastext);

}

为什么showhide会出现延迟? JavaScript 函数不是同步的吗? setTimeOut 不是可以防止参数函数在超时之前执行吗?如何在提交后立即隐藏对话框而不删除getSourceCode

【问题讨论】:

  • setTimeout(getSourceCode(),10000) 当您在getSourceCode() 中添加() 时,您将立即执行此处的功能。就做setTimeout(getSourceCode,10000)

标签: javascript synchronization settimeout delay


【解决方案1】:

问题出在这一行:

setTimeout(getSourceCode(),10000);

因为getSourceCode函数被立即调用(因为()在它之后),并且只有它的返回值传递给setTimeout

去掉你的函数后面的括号,然后你的函数将被传递给setTimeout,它会在内部调用它。

setTimeout(getSourceCode,10000);

【讨论】:

  • 已解决,谢谢。顺便说一句,您知道为什么在为函数设置超时之前代码似乎是异步的吗? JavaScript 函数不是默认同步的吗?
  • @Ursidae “似乎是异步的”是什么意思?
  • 正如我在问题中提到的,我希望getSourceCode 默认在showhide 的执行完成后运行,但现在我需要为getSourceCode 设置超时以实现这个。
  • @Ursidae JS 默认是同步的。你看到的是因为函数按照你的预期执行,但是只有图形更新,当一个任务(在本例中为onclick函数)完成时,并且由于JS是同步的,它只会在getSourceCode()之后发生。您可以通过将工作分成更小的任务来避免这种情况(这就是setTimeout 所做的)。你甚至可以使用延迟为 0 的setTimeout 来达到这个效果,因为它也会创建一个新任务。
  • 我不太明白你的意思...“仅图形更新”是什么意思?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 2011-01-03
  • 2020-07-02
  • 2021-02-27
相关资源
最近更新 更多