1

I have two functions, showhide and getSourceCode. I want showhide to execute (hide a dialog box) immediately after submit, but getSourceCode is pretty long so I make it execute later. However, some delay still occurs between I click submit and showhide comes to effect. When I remove getSourceCode, the dialog box can disappear immediately, but it is always delayed as long as there is getSourceCode, even when I setTimeout it.

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);

}

Why does delay occur in showhide? Aren't JavaScript functions synchronous? Isn't setTimeOut able to prevent the parameter function from execution before the timeout? How can I hide the dialog box right after submission, without removing getSourceCode?

Ursidae
  • 65
  • 6
  • `setTimeout(getSourceCode(),10000)` you are immediately executing the function here when you add the `()` in `getSourceCode()`. Just do `setTimeout(getSourceCode,10000)` – VLAZ May 16 '19 at 04:43

1 Answers1

0

The problem is in this line:

setTimeout(getSourceCode(),10000);

because getSourceCode function gets called immediately (because of () after it), and only its return value passed to setTimeout.

Remove the parentheses after your function, then, your function will be passed to setTimeout, and it will internally call it.

setTimeout(getSourceCode,10000);
FZs
  • 11,931
  • 11
  • 28
  • 41
  • It's solved and thanks. Btw, do you know why does the code seem to be asynchronous before setting a timeout to a function? Aren't JavaScript functions synchronous by default? – Ursidae May 16 '19 at 05:07
  • @Ursidae What do you mean "*seems asynchronous*"? – FZs May 16 '19 at 05:10
  • As I mentioned in the question, I expect `getSourceCode` to run after the execution of `showhide` has finished by default, but now I need to set a timeout to `getSourceCode` in order to achieve this. – Ursidae May 16 '19 at 05:18
  • @Ursidae JS is sync by default. What you see is because the functions are executed as you expect, but there are graphic updates only, when a task (in this case `onclick` function) is finished, and because JS is sync, it will only happen after `getSourceCode()`. You can avoid this by splitting work into smaller tasks (that's what `setTimeout` do). You can even use `setTimeout` with 0 delay, to achieve this effect, because it will create a new task too. – FZs May 16 '19 at 05:49
  • I don't really get what you mean... What means 'graphic updates only'? – Ursidae May 16 '19 at 07:14
  • @Ursidae I mean graphic updates in the browser. Only when a graphic update occur, will the look of the website change: changes made in DOM are only visualised that time. – FZs May 16 '19 at 13:23