innerHTML can't be trusted: Does not always execute synchronously

前端 未结 2 1730
轻奢々
轻奢々 2020-12-10 13:14

To see the problem in action, see this jsbin. Clicking on the button triggers the buttonHandler(), which looks like this:

function buttonHandle         


        
2条回答
  •  攒了一身酷
    2020-12-10 13:40

    1. I think the way it works is that the currently running code completes first, then all the page updates are done. In this case, calling longPrimeCalc causes more code to be executed, and only when it is done does the page update change.

    2. To fix this you have to have the currently running code terminate, then start the calculation in another context. You can do that with setTimeout. I'm not sure if there's any other way besides that.

    Here is a jsfiddle showing the behavior. You don't have to pass a callback to longPrimeCalc, you just have to create another function which does what you want with the return value. Essentially you want to defer the calculation to another "thread" of execution. Writing the code this way makes it obvious what you're doing (Updated again to make it potentially nicer):

    function defer(f, callback) {
      var proc = function() {
        result = f();
        if (callback) {
          callback(result);
        }
      }
      setTimeout(proc, 50);
    }
    
    function buttonHandler() {
      var elm = document.getElementById("progress");
      elm.innerHTML = "thinking...";
      defer(longPrimeCalc, function (isPrime) {
        if (isPrime) {
          elm.innerHTML = "It was a prime!";
        }
        else {
          elm.innerHTML = "It was not a prime =(";
        }
      });
    }
    

提交回复
热议问题