Blockly 애플리케이션은 종종 JavaScript를 출력 언어로 생성합니다. 일반적으로 웹페이지 내에서 실행됩니다 (아마도 동일하거나 삽입된 WebView). 다른 생성기와 마찬가지로 첫 번째 단계는 JavaScript 생성기를 포함하는 것입니다.
import {javascriptGenerator} from 'blockly/javascript';
작업공간에서 JavaScript를 생성하려면 다음을 호출합니다.
javascriptGenerator.addReservedWords('code');
var code = javascriptGenerator.workspaceToCode(workspace);
결과 코드는 도착 웹페이지에서 바로 실행할 수 있습니다.
try {
eval(code);
} catch (e) {
alert(e);
}
기본적으로 위의 스니펫은 코드를 생성하고 이를 평가합니다. 하지만
두 가지 개선 사항이 있습니다. 한 가지 개선 방법은 eval이
실패하지 않고 런타임 오류가 표시되도록 try
/catch
조용히 말이야. 또 다른 상세검색은 code
가 예약된
단어의 첫 번째 단어로, 사용자의 코드에 그 이름의 변수가 포함되어 있으면
자동으로 이름이 바뀌는 것을 가리킵니다. 모든 로컬 변수는
예약됩니다.
블록 강조표시
코드가 실행될 때 현재 실행 중인 블록을 강조 표시하면 사용자가
프로그램의 행동을 이해할 수 있습니다. 이미지, 동영상, 오디오, 텍스트 등의
앞에 STATEMENT_PREFIX
를 설정하여 문별 수준
코드를 생성합니다.
javascriptGenerator.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
javascriptGenerator.addReservedWords('highlightBlock');
작업공간에 블록을 표시하도록 highlightBlock
를 정의합니다.
function highlightBlock(id) {
workspace.highlightBlock(id);
}
이렇게 하면 highlightBlock('123');
문이 이전에 추가됩니다.
모든 문, 여기서 123
는 사용할 블록의 일련번호입니다.
강조표시됩니다.
무한 루프
결과 코드는 항상 구문상 올바르지만 무한 루프가 포함될 수 있습니다. 인코더-디코더 아키텍처를
문제 중지는
이러한 케이스를 처리하기 위한 가장 좋은 접근 방식은 Blockly의 범위 (!)입니다.
카운터를 유지하고 반복이 수행될 때마다 감소합니다.
이렇게 하려면 javascriptGenerator.INFINITE_LOOP_TRAP
를 코드로 설정하면 됩니다.
모든 루프와 함수에 삽입될 스니펫입니다. 다음은
예:
window.LoopTrap = 1000;
javascriptGenerator.INFINITE_LOOP_TRAP = 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n';
var code = javascriptGenerator.workspaceToCode(workspace);
예
다음은 라이브 데모 알아보겠습니다.
JS-Interpreter
사용자의 블록을 올바르게 실행하는 것이 중요합니다. JS-Interpreter 프로젝트를 진행하시기 바랍니다. 이 프로젝트는 Blockly와 별개이지만 Blockly를 위해 특별히 작성되었습니다.
- 어떤 속도에서든 코드를 실행합니다.
- 일시중지/재개/단계별 실행
- 블록이 실행될 때 강조 표시합니다.
- 브라우저의 JavaScript와 완전히 격리되어 있습니다.
인터프리터 실행
먼저 GitHub에서 JS 인터프리터를 다운로드합니다.
그런 다음 페이지에 추가합니다.
<script src="acorn_interpreter.js"></script>
이를 호출하는 가장 간단한 방법은 JavaScript를 생성하고 인터프리터를 만들고 코드를 실행하는 것입니다.
var code = javascriptGenerator.workspaceToCode(workspace);
var myInterpreter = new Interpreter(code);
myInterpreter.run();
인터프리터 단계
코드를 더 느리게 실행하거나 좀 더 제어된 방식으로 실행하려면
단계되는 루프 (이 경우 10밀리초마다 한 단계)로 run
를 호출합니다.
function nextStep() {
if (myInterpreter.step()) {
setTimeout(nextStep, 10);
}
}
nextStep();
각 단계는 선이나 블록이 아니라 JavaScript는 매우 세분화될 수 있습니다.
API 추가
JS 인터프리터는 브라우저에서 완전히 격리된 샌드박스입니다. 외부 세계와 작업을 실행하는 블록에는 인터프리터에 추가된 API가 필요합니다. 자세한 설명은 다음을 참조하세요. JS 인터프리터 문서. 그러나 우선, 알림 및 프롬프트 블록을 지원하는 데 필요한 API는 다음과 같습니다.
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));
}
그런 다음 initApi 함수를 전달하도록 인터프리터 초기화를 수정합니다.
var myInterpreter = new Interpreter(code, initApi);
알림 및 메시지 차단은 기본 차단 집합에서 유일한 블록 두 개임 인터프리터용 커스텀 API가 필요합니다
highlightBlock()
연결 중
JS 인터프리터에서 실행할 때는 highlightBlock()
를 실행해야 합니다.
즉시, 샌드박스 밖에 있는 것을 볼 수 있습니다. 해야 할 일
래퍼 함수 highlightBlock()
를 만들어 함수를 캡처합니다.
인수를 사용하고 네이티브 함수로 등록합니다.
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));
}
보다 정교한 애플리케이션은 시스템 리소스를 사용하지 않고 하이라이트 명령에 도달할 때까지 일시중지했다가 일시중지합니다 이 전략은 하나씩 실행합니다. 아래 예에서는 이 방법을 사용합니다.
JS 인터프리터 예
다음은 JavaScript를 단계별로 해석하는 실시간 데모입니다. 또한 이 데모는 다른 비동기 동작에 사용할 수 있는 좋은 예로서 대기 블록이 포함되어 있습니다. (예: 음성 또는 오디오, 사용자 입력)