Search code examples
javascripthtmlexecutioncheckpoint

Storing execution state in JavaScript? Can you resume later?


Is there anyway to do this? I want to create a JavaScript application that can "resume" application from the last checkpoint e.g.

//code.js
var abc = 13;
checkpoint("myLocalStorage");
alert(abc);

the checkpoint function will store every info about the execution such that in the future execution can be resumed right where it was left of as such:

//resume.js
resume("myLocalStorage");

This would be very helpful for executing long script / script with huge loops - I'm not talking about executing some tiny script that preloads images or do some funny animations. I'm talking about using JavaScript as a real number crunching tool where execution can take a long time and demands huge computing power. In these context you can see how useful execution checkpointing could be!

I suppose such thing doesn't exist for JavaScript yet, but if anyone ever comes close to something that remotely resembles it I would still be very grateful.


Solution

  • In order to make something that "suspend-able" in Javascript, you need to formulate things a little differently than you would in normal program.

    Step 1
    Decide how much of the problem you are able to do in one pass, for lack of a better word.

    Step 2
    Store the state in some kind of object. You have no intermediate values, just exactly what is needed to make the next pass

    Step 3
    Write the code so it can run with a window.setTimeout() function. This makes testing much easier than reloading the page.

    In this case, I have a program that converts my whole name to lower case, one step at a time. The only data I need to save is my name, and an index of where along the calculations I am.

    Example 1: Uses setTimeout()

    <html>
      <head>
        <title>Test Thingy</title>
      </head>
      <body>
      <script>
        var data = {
          name: ["Jeremy", "J", "Starcher"],
          idx: 0
        }
    
        function doPass() {
          // If at the end of the list
          if (data.idx >= data.name.length) {
            alert("All iterations done:" + data.name.join(" "));
            return;
          }
    
          // Do our calculation here
          var s = data.name[data.idx];
          s = s.toLowerCase();
          data.name[data.idx] = s;
          data.idx++;
          window.setTimeout(doPass);
        }
        doPass();
      </script>
    
      </body>
    </html>
    

    Example 2: Uses localStorage. Hit 'reload' 4 times to test

    <html>
      <head>
        <title>Test Thingy</title>
      </head>
      <body>
      <script>      
        var data;
        data = localStorage.getItem("data");    
        if (data) {
          data = JSON.parse(data);
        } else {
          data = {
            name: ["Jeremy", "J", "Starcher"],
            idx: 0
          }
        }
    
        function doPass() {
          // If at the end of the list
          if (data.idx >= data.name.length) {
            alert("All iterations done:" + data.name.join(" "));
            return;
          }
    
          // Do our calculation here
          var s = data.name[data.idx];
          alert(s);
          s = s.toLowerCase();
          data.name[data.idx] = s;
          data.idx++;
          localStorage.setItem("data", JSON.stringify(data));
        }
    
        doPass();
      </script>
    
      </body>
    </html>