JavaScript जनरेट करना और चलाना

Blockly ऐप्लिकेशन अक्सर अपनी आउटपुट भाषा के तौर पर JavaScript जनरेट करते हैं. आम तौर पर, ऐसा वेब पेज (संभवतः उसी या एम्बेड किए गए वेबव्यू) में चलाने के लिए किया जाता है. किसी भी जनरेटर की तरह, पहला कदम है 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 को रिज़र्व की गई सूची में जोड़ा गया है ताकि अगर उपयोगकर्ता के कोड में उस नाम का कोई वैरिएबल मौजूद है, तो टकराने के बजाय अपने आप उसका नाम बदल दिया गया. किसी भी लोकल वैरिएबल को इस तरह से रिज़र्व किया जाना चाहिए.

हाइलाइट ब्लॉक

कोड के इस्तेमाल के दौरान, मौजूदा ब्लॉक को हाइलाइट करने से उपयोगकर्ताओं को मदद मिलती है प्रोग्राम के व्यवहार को समझ सके. JavaScript कोड जनरेट करने से पहले 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);

उदाहरण

यहां है लाइव डेमो JavaScript को जनरेट और एक्ज़ीक्यूट करने की प्रोसेस के बारे में बताया गया है.

JS-अनुवादक

अगर आप उपयोगकर्ताओं को रोकने के लिए गंभीर हैं, तो ऐसा करने के लिए, JS-अनुवादक प्रोजेक्ट चुनें. यह प्रोजेक्ट, Blockly से अलग है, लेकिन इसे खास तौर पर Blockly के लिए लिखा गया है.

  • कोड को किसी भी स्पीड पर इस्तेमाल करें.
  • रोकें/फिर से शुरू करें/सिलसिलेवार तरीके से एक्ज़ीक्यूट करें.
  • ब्लॉक को एक्ज़ीक्यूट करने के दौरान उन्हें हाइलाइट करें.
  • ब्राउज़र के JavaScript से पूरी तरह अलग.

इंटरप्रेटर चलाएं

सबसे पहले, GitHub से JS-Interpreter डाउनलोड करें:

ZIP फ़ाइल डाउनलोड करें TAR Ball डाउनलोड करना GitHub पर देखें

इसके बाद, इसे अपने पेज पर जोड़ें:

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

इसे कॉल करने का सबसे आसान तरीका है JavaScript जनरेट करना, अनुवादक मोड में वीडियो अपलोड करें, और कोड को चलाएं:

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

अनुवादक मोड का इस्तेमाल करें

कोड को धीमा या ज़्यादा नियंत्रित तरीके से चलाने के लिए, मौजूदा run को एक लूप के साथ कॉल करें, जो यह कदम रखता है (इस मामले में हर 10 मिलीसेकंड में एक चरण):

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

ध्यान दें कि हर चरण कोई लाइन या ब्लॉक नहीं है, बल्कि यह JavaScript, जो कि बहुत ज़्यादा जटिल हो सकता है.

एपीआई जोड़ना

JS- interpreter एक सैंडबॉक्स है, जो ब्राउज़र से पूरी तरह से अलग होता है. बाहरी दुनिया के साथ कार्रवाइयां करने वाले किसी भी ब्लॉक के लिए, एपीआई को जोड़ना ज़रूरी है अनुवादक. पूरी जानकारी के लिए, देखें JS-अनुवादक दस्तावेज़. हालांकि, शुरू करने के लिए, यहां सूचना और प्रॉम्प्ट ब्लॉक के साथ काम करने वाला एपीआई दिया गया है:

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

ब्लॉक के डिफ़ॉल्ट सेट में, अलर्ट और प्रॉम्प्ट ब्लॉक ही दो ब्लॉक हैं जिसे अनुवादक के लिए कस्टम एपीआई की ज़रूरत होती है.

highlightBlock() को कनेक्ट कर रहा है

JS- interpreter में चलाते समय, 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 को समझने का लाइव डेमो दिया गया है. और यह डेमो इसमें एक प्रतीक्षा रोक शामिल है, जो अन्य एसिंक्रोनस व्यवहार के लिए उपयोग करने का एक अच्छा उदाहरण है (उदाहरण के लिए, बोली या ऑडियो, उपयोगकर्ता का इनपुट).