JavaScript Oluşturma ve Çalıştırma

Engellenen uygulamalar, genellikle bir web sayfası içinde (büyük olasılıkla aynı veya yerleşik bir Web Görünümü) çalışmak üzere çıkış dili olarak JavaScript oluşturur. Tüm içerik oluşturucularda olduğu gibi ilk adım, JavaScript oluşturucuyu eklemektir.

import {javascriptGenerator} from 'blockly/javascript';

Çalışma alanından JavaScript oluşturmak için şu çağrıyı yapın:

javascriptGenerator.addReservedWords('code');
var code = javascriptGenerator.workspaceToCode(workspace);

Oluşturulan kod doğrudan hedef web sayfasında yürütülebilir:

try {
  eval(code);
} catch (e) {
  alert(e);
}

Temel olarak yukarıdaki snippet yalnızca kodu oluşturur ve değerlendirir. Ancak, birkaç ayrıntılandırma vardır. Ayrıntılandırmalardan biri, değerlendirmenin bir try/catch içine sarmalanmasıdır. Böylece, çalışma zamanı hataları sorunsuz bir şekilde başarısız olmak yerine görünür olur. Bir başka ayrıntılandırma da code'in ayrılmış kelimeler listesine eklenmesidir. Böylece, kullanıcının kodu bu ada sahip bir değişken içeriyorsa çarpışmak yerine otomatik olarak yeniden adlandırılır. Tüm yerel değişkenler bu şekilde ayrılmalıdır.

Blokları Vurgula

Kod çalışırken o anda yürütülen bloku vurgulamak, kullanıcıların programlarının davranışını anlamasına yardımcı olur. Vurgulama, JavaScript kodu oluşturulmadan önce STATEMENT_PREFIX değeri ayarlanarak ifade bazında yapılabilir:

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

Bloğu çalışma alanında işaretlemek için highlightBlock öğesini tanımlayın.

function highlightBlock(id) {
  workspace.highlightBlock(id);
}

Bu, her ifadeden önce highlightBlock('123'); ifadesinin eklenmesiyle sonuçlanır. Burada 123, vurgulanacak bloğun seri numarasıdır.

Sonsuz Döngüler

Ortaya çıkan kodun söz diziminin her zaman doğru olması garanti edilse de sonsuz döngüler içerebilir. Durdurma problemini çözmek Blockly'nin kapsamının (!) dışında olduğundan, bu durumlarla başa çıkmaya yönelik en iyi yaklaşım bir karşıt koymak ve her iterasyonda bunu azaltmaktır. Bunu başarmak için javascriptGenerator.INFINITE_LOOP_TRAP özelliğini her döngüye ve her işleve eklenecek bir kod snippet'ine ayarlamanız yeterlidir. Bir örnek verelim:

window.LoopTrap = 1000;
javascriptGenerator.INFINITE_LOOP_TRAP = 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n';
var code = javascriptGenerator.workspaceToCode(workspace);

Örnek

JavaScript oluşturma ve yürütmeyle ilgili canlı bir demoyu burada bulabilirsiniz.

JS Çevirmeni

Kullanıcının bloklarını düzgün bir şekilde çalıştırma konusunda ciddiyseniz JS-Çevirmen projesini kullanmanız önerilir. Bu proje, Blockly'den ayrıdır, ancak özellikle Blockly için yazılmıştır.

  • İstediğiniz hızda kod çalıştırın.
  • Yürütmeyi duraklatma/devam ettirme/adım adım yürütme.
  • Yürütülen blokları vurgulayın.
  • Tarayıcının JavaScript'inden tamamen izole edilmiştir.

Çevirmeni Çalıştırma

Öncelikle, GitHub'dan JS-Çevirmenini indirin:

ZIP dosyasını indir TAR Ball'u indir GitHub'da Göster

Ardından bu sayfayı sayfanıza ekleyin:

<script src="acorn_interpreter.js"></script>

En basit yöntem, JavaScript oluşturmak, yorumlayıcıyı oluşturmak ve kodu çalıştırmaktır:

var code = javascriptGenerator.workspaceToCode(workspace);
var myInterpreter = new Interpreter(code);
myInterpreter.run();

Çevirmene Adım Atma

Kodu daha yavaş veya daha kontrollü bir şekilde yürütmek için run çağrısını şu adımları oluşturan bir döngüyle değiştirin (bu örnekte 10 ms'de bir adım):

function nextStep() {
  if (myInterpreter.step()) {
    setTimeout(nextStep, 10);
  }
}
nextStep();

Her adımın bir çizgi veya blok olmadığını, JavaScript'te anlamsal bir birim olduğunu ve son derece ayrıntılı olabileceğini unutmayın.

API ekleyin

JS Çevirmeni, tarayıcıdan tamamen izole edilmiş bir korumalı alandır. Dış dünyayla işlemler gerçekleştiren tüm bloklar için çevirmene eklenmiş bir API gerekir. Tam açıklama için JS Çevirmeni dokümanlarına bakın. Öncelikle, uyarı ve istem bloklarını desteklemek için gereken API şunlardır:

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));
}

Ardından çevirmen başlatmanızı initApi işlevini geçecek şekilde değiştirin:

var myInterpreter = new Interpreter(code, initApi);

Uyarı ve istem blokları, varsayılan blok grubunda çevirmen için özel API gerektiren yalnızca iki bloktur.

highlightBlock() bağlanıyor

JS Çevirmeni'nde çalışırken highlightBlock(), kullanıcı programda ilerlerken korumalı alanın dışında hemen yürütülmelidir. Bunu yapmak için işlev bağımsız değişkenini yakalamak üzere bir sarmalayıcı işlevi highlightBlock() oluşturun ve bunu yerel bir işlev olarak kaydedin.

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));
}

Daha gelişmiş uygulamalar, bir vurgulama komutuna ulaşılana kadar adımları duraklatma olmadan art arda yürütmek ve ardından duraklatmak isteyebilir. Bu strateji, satır satır yürütmeyi simüle eder. Aşağıdaki örnekte bu yaklaşım kullanılmaktadır.

JS Çevirmen Örneği

JavaScript'i adım adım yorumlamayı gösteren canlı bir demoyu burada bulabilirsiniz. Bu demoda ise diğer eşzamansız davranışlar (ör. konuşma veya ses, kullanıcı girişi) için iyi bir örnek olan bekleme bloğu bulunmaktadır.