Blockanwendungen generieren oft JavaScript als Ausgabesprache, im Allgemeinen auf einer Webseite ausgeführt werden (möglicherweise dieselbe oder eine eingebettete WebView). Wie bei jedem Generator muss zuerst der JavaScript-Generator eingebunden werden.
import {javascriptGenerator} from 'blockly/javascript';
Um JavaScript-Code aus dem Arbeitsbereich zu generieren, rufen Sie Folgendes auf:
javascriptGenerator.addReservedWords('code');
var code = javascriptGenerator.workspaceToCode(workspace);
Der resultierende Code kann direkt auf der Zielwebseite ausgeführt werden:
try {
eval(code);
} catch (e) {
alert(e);
}
Im Grunde generiert das obige Snippet nur den Code und wertet ihn aus. Sie können jedoch
gibt es einige Verfeinerungen. Eine Verfeinerung besteht darin,
dass die Bewertung in
try
/catch
, damit alle Laufzeitfehler sichtbar sind und nicht fehlschlagen
leise. Außerdem wird code
der Liste der reservierten Wörter hinzugefügt. Wenn der Code des Nutzers also eine Variable mit diesem Namen enthält, wird sie automatisch umbenannt, anstatt dass es zu einer Kollision kommt. Alle lokalen Variablen sollten
die auf diese Weise reserviert sind.
Blöcke hervorheben
Wenn der aktuell ausgeführte Block während der Ausführung des Codes hervorgehoben wird, können Nutzer das Verhalten ihres Programms besser nachvollziehen. Die Markierung kann auf einem
Anweisungsebene durch Festlegen von STATEMENT_PREFIX
vor
Generieren des JavaScript-Codes:
javascriptGenerator.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
javascriptGenerator.addReservedWords('highlightBlock');
Definieren Sie highlightBlock
, um den Block im Arbeitsbereich zu markieren.
function highlightBlock(id) {
workspace.highlightBlock(id);
}
Dies führt dazu, dass die Anweisung highlightBlock('123');
vor dem
in jeder Anweisung, wobei 123
die Seriennummer des Blocks ist, der verwendet werden soll
hervorgehoben.
Endlosschleifen
Auch wenn der resultierende Code garantiert syntaktisch korrekt ist
kann er Endlosschleifen enthalten. Seit der Lösung des
Das Anhalten des Problems
Blocklys Aufgabenbereich (!) ist der beste Ansatz für den Umgang mit solchen Fällen,
einen Zähler verwalten und bei jeder
Durchführung dekrementiert werden.
Legen Sie dazu einfach javascriptGenerator.INFINITE_LOOP_TRAP
auf einen Code fest.
Snippet, das in jede Schleife und Funktion eingefügt wird. Hier ein Beispiel:
window.LoopTrap = 1000;
javascriptGenerator.INFINITE_LOOP_TRAP = 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n';
var code = javascriptGenerator.workspaceToCode(workspace);
Beispiel
Hier ist eine Live-Demo das Generieren und Ausführen von JavaScript.
JS-Interpreter
Wenn es Ihnen wichtig ist, die Nutzerblöcke korrekt auszuführen, JS-Interpreter-Projekt ist die richtige Wahl. Dieses Projekt ist unabhängig von Blockly, wurde aber speziell für Blockly geschrieben.
- Sie können Code mit jeder Geschwindigkeit ausführen.
- Ausführung pausieren/fortsetzen/schrittweise ausführen.
- Blöcke beim Ausführen hervorheben
- Vollständig vom JavaScript des Browsers isoliert.
Dolmetscher ausführen
Laden Sie zuerst den JS-Interpreter von GitHub herunter:
Fügen Sie es dann zu Ihrer Seite hinzu:
<script src="acorn_interpreter.js"></script>
Die einfachste Methode zum Aufrufen besteht darin, das JavaScript zu generieren, den Interpreter zu erstellen und den Code auszuführen:
var code = javascriptGenerator.workspaceToCode(workspace);
var myInterpreter = new Interpreter(code);
myInterpreter.run();
Schritt für Schritt Dolmetscher
Um den Code langsamer oder kontrollierter auszuführen, ersetzen Sie den Parameter
Aufruf von run
mit einer Schleife (in diesem Fall ein Schritt alle 10 ms):
function nextStep() {
if (myInterpreter.step()) {
setTimeout(nextStep, 10);
}
}
nextStep();
Jeder Schritt ist keine Linie oder Block, sondern eine semantische Einheit in JavaScript-Code, der sehr detailliert sein kann.
API hinzufügen
Der JS-Interpreter ist eine Sandbox, die vollständig vom Browser isoliert ist. Für alle Blöcke, die Aktionen mit der Außenwelt durchführen, ist eine API erforderlich, die für den Dolmetscher. Eine vollständige Beschreibung finden Sie in der JS-Interpreter-Dokumentation Hier ist jedoch zuerst die API, die zur Unterstützung der Blockierungen für Warnungen und Aufforderungen erforderlich ist:
function initApi(interpreter, globalObject) {
// Add an API function for the alert() block.
var wrapper = function(text) {
return alert(arguments.length ? text : '');
};
interpreter.setProperty(globalObject, 'alert',
interpreter.createNativeFunction(wrapper));
// Add an API function for the prompt() block.
wrapper = function(text) {
return prompt(text);
};
interpreter.setProperty(globalObject, 'prompt',
interpreter.createNativeFunction(wrapper));
}
Ändern Sie dann die Interpreter-Initialisierung, um die initApi-Funktion zu übergeben:
var myInterpreter = new Interpreter(code, initApi);
Die Blockierungen mit Benachrichtigungen und Aufforderungen sind die einzigen beiden Blockierungen in der Standardreihe. die eine benutzerdefinierte API für den Interpreter erfordern.
Verknüpfung mit highlightBlock()
wird hergestellt
Bei Ausführung im JS-Interpreter sollte highlightBlock()
ausgeführt werden.
direkt außerhalb der Sandbox, während der Nutzer das Programm durchläuft. Aufgabe
Erstellen Sie die Wrapper-Funktion highlightBlock()
, um die Funktion
-Argument und registrieren Sie es als native Funktion.
function initApi(interpreter, globalObject) {
// Add an API function for highlighting blocks.
var wrapper = function(id) {
return workspace.highlightBlock(id);
};
interpreter.setProperty(globalObject, 'highlightBlock',
interpreter.createNativeFunction(wrapper));
}
Komplexere Anwendungen möchten möglicherweise wiederholt Schritte ausführen, halten Sie an, bis ein Hervorhebungsbefehl erreicht ist, und halten Sie dann an. Diese Strategie simuliert die zeilenweise Ausführung. Im folgenden Beispiel wird dieser Ansatz verwendet.
JS-Interpreter-Beispiel
Hier ist eine Live-Demo der Interpretation von JavaScript. Und dieser Demo enthält einen Warteblock, ein gutes Beispiel für ein anderes asynchrones Verhalten (z.B. Sprache oder Audio, Nutzereingabe).