javascript - JS 在生成的函数中等待/暂停

标签 javascript blockly

我在做什么

我正在使用 Blockly 构建海龟图形应用程序。用户可以从 block 构建代码,然后 Blockly 引擎生成 JS 代码,绘制到 Canvas 上。

我的问题是什么

Blockly 引擎生成 JS 代码,但将其作为字符串返回,我必须通过 eval() 将其绘制到 Canvas 上。

我可以更改 block 的代码以生成不同的输出,但保持它尽可能简单很重要,因为用户可以阅读 block 输入背后的实际代码。所以我不想把它搞砸。

我想做什么

我可以完全控制原子操作(goturn 等),所以我想在开头插入一小段代码函数,这会延迟其余函数体的执行。像这样的东西:

function go(dir, dist) {
  // wait here a little

  // do the drawing
}

我认为它应该是同步的,它可以在执行流程中保持延迟。我尝试使用 setTimeout(异步,失败)、promise(失败)、循环中的时间戳检查(失败)。

在 JS 中甚至可能吗?

最佳答案

您不能让代码同步等待。您唯一会得到的是一个卡住的浏览器窗口。

您需要的是使用 js interpreter而不是评估。通过这种方式,您可以暂停执行、播放动画、突出显示当前正在执行的 block 等……教程中有许多示例可以帮助您入门。这是一个工作代码,基于 JS interpreter example :

var workspace = Blockly.inject("editor-div", {
  toolbox: document.getElementById('toolbox')
});

Blockly.JavaScript.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
Blockly.JavaScript.addReservedWords('highlightBlock');

Blockly.JavaScript['text_print'] = function(block) {
  var argument0 = Blockly.JavaScript.valueToCode(
    block, 'TEXT',
    Blockly.JavaScript.ORDER_FUNCTION_CALL
  ) || '\'\'';
  return "print(" + argument0 + ');\n';
};

function run() {
  var code = Blockly.JavaScript.workspaceToCode(workspace);
  var running = false;

  workspace.traceOn(true);
  workspace.highlightBlock(null);

  var lastBlockToHighlight = null;
  var myInterpreter = new Interpreter(code, (interpreter, scope) => {
    interpreter.setProperty(
      scope, 'highlightBlock',
      interpreter.createNativeFunction(id => {
        id = id ? id.toString() : '';
        running = false;
        workspace.highlightBlock(lastBlockToHighlight);
        lastBlockToHighlight = id;
      })
    );
    interpreter.setProperty(
      scope, 'print',
      interpreter.createNativeFunction(val => {
        val = val ? val.toString() : '';
        console.log(val);
      })
    );
  });

  var intervalId = setInterval(() => {
    running = true;
    while (running) {
      if (!myInterpreter.step()) {
        workspace.highlightBlock(lastBlockToHighlight);
        clearInterval(intervalId);
        return;
      }
    }
  }, 500);
}
#editor-div {
  width: 500px;
  height: 150px;
}
<script src="https://rawgit.com/google/blockly/master/blockly_compressed.js"></script>
<script src="https://rawgit.com/google/blockly/master/blocks_compressed.js"></script>
<script src="https://rawgit.com/google/blockly/master/javascript_compressed.js"></script>
<script src="https://rawgit.com/google/blockly/master/msg/js/en.js"></script>
<script src="https://rawgit.com/NeilFraser/JS-Interpreter/master/acorn_interpreter.js"></script>

<xml id="toolbox" style="display: none">
  <block type="text"></block>
  <block type="text_print"></block>
  <block type="controls_repeat_ext"></block>
 <block type="math_number"></block>
</xml>

<div>
  <button id="run-code" onclick="run()">run</button>
</div>
<div id="editor-div"></div>

编辑

添加了变量running 来控制解释器。现在它会跳过,直到 running 变量设置为 false,因此 highlightBlock 函数内的 running = false 语句实际上用作断点。

编辑

引入了lastBlockToHighlight 变量来延迟突出显示,因此突出显示最新的运行语句,而不是下一个。遗憾的是,JavaScript 代码生成器没有类似于 STATEMENT_PREFIXSTATEMENT_SUFFIX 配置。

关于javascript - JS 在生成的函数中等待/暂停,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39069363/

相关文章:

python - 如何在浏览器中直接执行 Blockly 生成的 Python 代码?

development-environment - 是否有具有大/可配置舞台分辨率的可视化编程语言?

javascript - Blockchain API Help - 如何检查支付是否完成?

javascript - 无法在组合框 Jquery Mobile 上清空()

javascript - 需要有关函数的帮助

javascript - 如何使用 Blockly 生成的代码?

javascript - 如何使用 Javascript 创建 Blockly block 的实例?

javascript - 如何将键盘箭头与 jCarousel 集成 - 使用 Keynav jQuery 插件?

javascript - JQuery .attr 标签不工作

javascript - Blockly 中不寻常的 JavaScript for 循环与 xml