DOM refresh on long running function

后端 未结 12 2291
醉话见心
醉话见心 2020-11-27 20:54

I have a button which runs a long running function when it\'s clicked. Now, while the function is running, I want to change the button text, but I\'m having problems in some

12条回答
  •  無奈伤痛
    2020-11-27 21:43

    As of 2019 one uses double requesAnimationFrame to skip a frame instead of creating a race condition using setTimeout.

    function doRun() {
        document.getElementById('app').innerHTML = 'Processing JS...';
        requestAnimationFrame(() =>
        requestAnimationFrame(function(){
             //blocks render
             confirm('Heavy load done') 
             document.getElementById('app').innerHTML = 'Processing JS... done';
        }))
    }
    doRun()


    As an usage example think of calculating pi using Monte Carlo in an endless loop:

    using for loop to mock while(true) - as this breaks the page

    function* piMonteCarlo(r = 5, yield_cycle = 10000){
    
      let total = 0, hits = 0, x=0, y=0, rsqrd = Math.pow(r, 2);
      
      while(true){
      
         total++;
         if(total === Number.MAX_SAFE_INTEGER){
          break;
         }
         x = Math.random() * r * 2 - r;
         y = Math.random() * r * 2 - r;
         
         (Math.pow(x,2) + Math.pow(y,2) < rsqrd) && hits++;
         
         if(total % yield_cycle === 0){
          yield 4 * hits / total
         }
      }
    }
    
    let pi_gen = piMonteCarlo(5, 1000), pi = 3;
    
    for(let i = 0; i < 1000; i++){
    // mocks
    // while(true){
    // basically last value will be rendered only
      pi = pi_gen.next().value
      console.log(pi)
      document.getElementById('app').innerHTML = "PI: " + pi
    }

    And now think about using requestAnimationFrame for updates in between ;)

    function* piMonteCarlo(r = 5, yield_cycle = 10000){
    
      let total = 0, hits = 0, x=0, y=0, rsqrd = Math.pow(r, 2);
      
      while(true){
      
         total++;
         if(total === Number.MAX_SAFE_INTEGER){
          break;
         }
         x = Math.random() * r * 2 - r;
         y = Math.random() * r * 2 - r;
         
         (Math.pow(x,2) + Math.pow(y,2) < rsqrd) && hits++;
         
         if(total % yield_cycle === 0){
          yield 4 * hits / total
         }
      }
    }
    
    let pi_gen = piMonteCarlo(5, 1000), pi = 3;
    
    
    function rAFLoop(calculate){
    
      return new Promise(resolve => {
        requestAnimationFrame( () => {
        requestAnimationFrame(() => {
          typeof calculate === "function" && calculate()
          resolve()
        })
        })
      })
    }
    let stopped = false
    async function piDOM(){
      while(stopped==false){
        await rAFLoop(() => {
          pi = pi_gen.next().value
          console.log(pi)
          document.getElementById('app').innerHTML = "PI: " + pi
        })
      }
    }
    function stop(){
      stopped = true;
    }
    function start(){
      if(stopped){
        stopped = false
        piDOM()
      }
    }
    piDOM()

提交回复
热议问题