最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - How do I allow a webpage to update while a javascript is running? - Stack Overflow

programmeradmin0浏览0评论

There has to be an easy way to do this, but I'm new to JS.

I have a javascript program that (1) takes user input, (2) updates the webpage based on that input, then (3) performs a lengthy calculation. The trouble is that the webpage doesn't register the update till after the lengthy calculation. Isn't there a way to pause execution so that the page can update before the long calculation?

I've tried setTimeout and window.setTimeout, but they made no difference.

The program is for playing a game: the user inputs a move, the script updates the position, then calculates its next move. postMessage prints text messages using div.innerHTML; buttonFn takes the input from the user, updates the position, prints a message, then starts the puter calculating.

function buttonFn(arg){
    var hst = histButt;
    hst.push(arg);
    var nwmv = hst.clone();

    postMessage("New move: " + nwmv.join());
    if(status == opposite(p) && !pauseQ){
    var mvsposs = movesFromPos(posCur,status);
    if(mvsposs.has(nwmv)){
        updatePosCur(nwmv);
        //waitasec();
        if(p == status && !pauseQ){
        pTurn();
        };
    }
    else{
        histButt = nwmv;
    };
    };
};

There has to be an easy way to do this, but I'm new to JS.

I have a javascript program that (1) takes user input, (2) updates the webpage based on that input, then (3) performs a lengthy calculation. The trouble is that the webpage doesn't register the update till after the lengthy calculation. Isn't there a way to pause execution so that the page can update before the long calculation?

I've tried setTimeout and window.setTimeout, but they made no difference.

The program is for playing a game: the user inputs a move, the script updates the position, then calculates its next move. postMessage prints text messages using div.innerHTML; buttonFn takes the input from the user, updates the position, prints a message, then starts the puter calculating.

function buttonFn(arg){
    var hst = histButt;
    hst.push(arg);
    var nwmv = hst.clone();

    postMessage("New move: " + nwmv.join());
    if(status == opposite(p) && !pauseQ){
    var mvsposs = movesFromPos(posCur,status);
    if(mvsposs.has(nwmv)){
        updatePosCur(nwmv);
        //waitasec();
        if(p == status && !pauseQ){
        pTurn();
        };
    }
    else{
        histButt = nwmv;
    };
    };
};
Share Improve this question edited Oct 15, 2010 at 2:40 Andrew Dabrowski asked Oct 15, 2010 at 2:18 Andrew DabrowskiAndrew Dabrowski 631 silver badge7 bronze badges 7
  • 1 A code sample would help here... – deceze Commented Oct 15, 2010 at 2:20
  • all process are being processed on client side? – rob waminal Commented Oct 15, 2010 at 2:22
  • function postMessage(txt){ messageHist.push(txt); messageHist = messageHist.slice(1); var mesdiv = document.getElementById("messageDiv"); //messageHist.reverse(); mesdiv.innerHTML = messageHist.join("<br />"); //messageHist.reverse(); }; – Andrew Dabrowski Commented Oct 15, 2010 at 2:24
  • 1 use a spinner while processing stackoverflow./questions/51352/… – zod Commented Oct 15, 2010 at 2:28
  • 1 Put the code in the original question, not the ments – epascarello Commented Oct 15, 2010 at 2:29
 |  Show 2 more ments

4 Answers 4

Reset to default 7

yes there is, call your function like this. Using setTimeout will allow a page reflow prior to your JS executing.

function buttonFn(arg){
    var hst = histButt;
    hst.push(arg);
    var nwmv = hst.clone();

    postMessage("New move: " + nwmv.join());
    if(status == opposite(p) && !pauseQ){
    var mvsposs = movesFromPos(posCur,status);
    if(mvsposs.has(nwmv)){
        updatePosCur(nwmv);
        //waitasec();

        if(p == status && !pauseQ){
        setTimeout(function(){
          pTurn();
        },0);

        };
    }
    else{
        histButt = nwmv;
    };
    };
};

Remember, JS is very event driven friendly. If you can move things off, and call them later do it. Thats the only way we can support multi-threaded like behavior.

setTimeout

If you only need to support modern browsers (or if you use a transpiler), you can now use ES6 features to make this much easier and more in the style the original questioner was trying to do. (I realize the question is 8 years old - no harm in a new, more current answer!)

For example you can do something like this:

// helper function to use a setTimeout as a promise.
function allowUpdate() {
  return new Promise((f) => {
    setTimeout(f, 0);
  });
}

// An infinitely looping operation that doesn't crash the browser.
async function neverStopUpdating(someElement) {
  let i = 0;
  while (true) {
    someElement.innerText = i;
    i++;
    await allowUpdate();
  }
}

If you're trying to do a hard putation you'll want to make sure not to do this await too frequently - in this example, in Chrome at time of writing, i only increments by about 150 per second because the context switch of a setTimeout is not fast (where you'd get hundreds of thousands in a second if you didn't yield for updates). You'd likely want to find a balance, either always perform some number of iterations before allowing an update, or maybe eg. call Date.now() in your loop and yield for an update whenever 100ms have passed since the last time you allowed an update.

You can do the update, wait for a bit of time, than do the calculation.

OR

You can use webworkers on browsers that support them.

Without having actual code, that is the best answer that I can give you.

JavaScript is single threaded. If you do your calc server side you could get the results via ajax which is called asynchronously, not blocking your ui.

发布评论

评论列表(0)

  1. 暂无评论