【问题标题】:Storing execution state in JavaScript? Can you resume later?在 JavaScript 中存储执行状态?以后可以继续吗?
【发布时间】:2012-10-03 03:07:19
【问题描述】:

有没有办法做到这一点?我想创建一个 JavaScript 应用程序,可以从最后一个检查点“恢复”应用程序,例如

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

检查点函数将存储有关执行的所有信息,以便将来可以从原来的位置继续执行:

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

这对于执行带有巨大循环的长脚本/脚本非常有帮助 - 我不是在谈论执行一些预加载图像或做一些有趣动画的小脚本。我说的是使用 JavaScript 作为实数运算工具,其中执行可能需要很长时间并且需要巨大的计算能力。在这些上下文中,您可以看到执行检查点有多么有用!

我想 JavaScript 尚不存在这样的东西,但如果有人接近类似它的东西,我仍然会非常感激。

【问题讨论】:

  • 出于好奇,您知道任何语言具有这样的功能吗?
  • @GGG:C 有 setjmp() 和 longjmp()。另请参阅 C# 5 异步或协程。
  • @SLaks 出于某种原因,我认为应该保存程序状态,并且应该跨会话工作......也许我读错了问题。

标签: javascript html execution checkpoint


【解决方案1】:

为了在 Javascript 中创建“可挂起”的东西,你需要用不同于普通程序的方式来制定一些东西。

第 1 步
决定你能在一次pass中解决多少问题,因为没有更好的词。

第 2 步
将状态存储在某种对象中。您没有中间值,只是进行下一次 pass

所需的值

第 3 步
编写代码,使其可以使用window.setTimeout() 函数运行。这使得测试比重新加载页面容易得多。

在这种情况下,我有一个程序将我的全名转换为小写,一次一步。我需要保存的唯一数据是我的姓名,以及我所在位置的索引。

示例1:使用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>

示例 2:使用 localStorage。点击“重新加载”4次进行测试

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

【讨论】:

  • 谢谢。我想到了你的第二种方法,这绝对是一个很好的方法,但我在想一些对我们平台用户来说更透明的方法。如果您考虑调用具有副作用的其他函数的可能性,我认为可能很难跟踪所有执行状态
  • @GaneshwaraHerawanHanandaPut -- 哦,我完全理解跟踪执行状态是多么困难,这就是为什么知道在哪里拆分事情至关重要。任何迭代问题都需要在每次重新加载时处理一次 passiteration,而不是尝试只进行迭代的一部分。我无法想象你会得到一个更简单的解决方案。
  • 是的,看来这些毕竟是最好的解决方案。谢谢。问候,Ganesh
【解决方案2】:

Javascript 不是为“[存储] 实数运算工具而设计的,其中执行可能需要很长时间并且需要巨大的计算能力”。这是您将获得的最好的:http://www.w3schools.com/html/html5_webstorage.asp

【讨论】:

    【解决方案3】:

    最新浏览器支持yield。我们可以调查一下。

    https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.7

    【讨论】:

    • 你能告诉我这有什么帮助吗?我从我对 Scala 的一点经验中知道收益,并且这个特性对于生成集合的元素很有用。但我看不出这如何帮助解决我的问题。问候,Ganesh
    • @GaneshwaraHerawanHanandaPut Scala yield 是完全不同的东西。在这个答案的上下文中,yield 表示执行线程暂时放弃执行,因此可以运行不同的东西。这种自愿让步与先发制人的多任务处理形成鲜明对比。
    猜你喜欢
    • 2019-07-08
    • 1970-01-01
    • 2018-04-10
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    相关资源
    最近更新 更多