في برمجة تطبيقات Google وJavaScript، يحتوي وقت التشغيل أو بيئة وقت التشغيل على محرّك JavaScript الذي يحلّل رمز النص البرمجي وينفّذه. يوفر وقت التشغيل قواعد حول كيفية الوصول إلى الذاكرة، وكيفية تفاعل البرنامج مع نظام تشغيل الكمبيوتر، وما هي بنية البرنامج المسموح بها. يتضمّن كل متصفّح ويب بيئة وقت تشغيل لـ JavaScript.
في السابق، كانت "برمجة تطبيقات Google" تستخدم برنامج Rhino لتفسير JavaScript من Mozilla. على الرغم من أنّ Rhino وفّرت طريقة ملائمة لتنفيذ النصوص البرمجية للمطوّرين في "برمجة التطبيقات"، إلا أنّها ربطت "برمجة التطبيقات" بإصدار معيّن من JavaScript (ES5). لا يمكن لمطوّري برمجة تطبيقات استخدام بنية وميزات JavaScript الحديثة في النصوص البرمجية التي تستخدم وقت تشغيل Rhino.
لحلّ هذه المشكلة، أصبحت خدمة برمجة تطبيقات متوافقة الآن مع وقت التشغيل V8 الذي يتيح استخدام Chrome وNode.js. نقل النصوص البرمجية الحالية إلى V8 للاستفادة من أحدث ميزات وتركيبات JavaScript
توضّح هذه الصفحة الميزات الجديدة التي يتيحها V8 وكيفية تفعيله لاستخدامه في النصوص البرمجية. توضّح مقالة نقل النصوص البرمجية إلى V8 الخطوات اللازمة لنقل النصوص البرمجية الحالية لاستخدام وقت التشغيل V8.
ميزات وقت التشغيل V8
يمكن للنصوص البرمجية التي تستخدم وقت التشغيل V8 الاستفادة من الميزات التالية:
بنية ECMAScript الحديثة
استخدِم بنية ECMAScript الحديثة في النصوص البرمجية التي يتم تشغيلها باستخدام V8. تتضمّن هذه البنية let وconst والعديد من الميزات الشائعة الأخرى.
يمكنك الاطّلاع على أمثلة على بنية V8 للحصول على قائمة قصيرة بالتحسينات الشائعة على البنية التي يمكنك إجراؤها باستخدام وقت التشغيل V8.
تتضمّن بيئة تشغيل V8 في Apps Script بعض القيود والاختلافات الرئيسية مقارنةً ببيئات تشغيل JavaScript الشائعة الأخرى. لمزيد من التفاصيل، يُرجى الاطّلاع على قيود وقت التشغيل V8 في "برمجة تطبيقات Google".
تحسين رصد الوظائف
تم تحسين عملية رصد الدوال في "برمجة تطبيقات Google" للنصوص البرمجية التي تستخدم V8. يتعرّف وقت التشغيل الجديد على تنسيقات تعريف الدوال التالية:
function normalFunction() {} async function asyncFunction() {} function* generatorFunction() {} var varFunction = function() {} let letFunction = function() {} const constFunction = function() {} var namedVarFunction = function alternateNameVarFunction() {} let namedLetFunction = function alternateNameLetFunction() {} const namedConstFunction = function alternateNameConstFunction() {} var varAsyncFunction = async function() {} let letAsyncFunction = async function() {} const constAsyncFunction = async function() {} var namedVarAsyncFunction = async function alternateNameVarAsyncFunction() {} let namedLetAsyncFunction = async function alternateNameLetAsyncFunction() {} const namedConstAsyncFunction = async function alternateNameConstAsyncFunction() {} var varGeneratorFunction = function*() {} let letGeneratorFunction = function*() {} const constGeneratorFunction = function*() {} var namedVarGeneratorFunction = function* alternateNameVarGeneratorFunction() {} let namedLetGeneratorFunction = function* alternateNameLetGeneratorFunction() {} const namedConstGeneratorFunction = function* alternateNameConstGeneratorFunction() {} var varLambda = () => {} let letLambda = () => {} const constLambda = () => {} var varAsyncLambda = async () => {} let letAsyncLambda = async () => {} const constAsyncLambda = async () => {}
استدعاء طرق عناصر الاتصال من المشغّلات وعمليات رد الاتصال
يمكن للنصوص البرمجية التي تستخدم V8 استدعاء طرق الكائنات وطرق الفئات الثابتة من المواضع التي يمكنك فيها استدعاء طرق المكتبة. تشمل هذه الأماكن ما يلي:
- مشغّلات ملف البيان في إضافات Google Workspace
- علامات التشغيل القابلة للتثبيت
- عناصر القائمة في أدوات تحرير Google Workspace
- دوال رد الاتصال الخاصة بالمستخدم، مثل تلك الموضّحة في
عينة تعليمات برمجية
ScriptApp.newStateToken()
يوضّح مثال V8 التالي كيفية استخدام طرق العناصر عند إنشاء عناصر القائمة في "جداول بيانات Google":
function onOpen() {
const ui = SpreadsheetApp.getUi(); // Or DocumentApp, SlidesApp, or FormApp.
ui.createMenu('Custom Menu')
.addItem('First item', 'menu.item1')
.addSeparator()
.addSubMenu(ui.createMenu('Sub-menu')
.addItem('Second item', 'menu.item2'))
.addToUi();
}
const menu = {
item1: function() {
SpreadsheetApp.getUi().alert('You clicked: First item');
},
item2: function() {
SpreadsheetApp.getUi().alert('You clicked: Second item');
}
}
عرض السجلات
توفّر برمجة تطبيقات خدمتَين لتسجيل البيانات، وهما خدمة Logger وفئة console. تكتب كلتا الخدمتين السجلات إلى خدمة Stackdriver Logging نفسها.
لعرض سجلّات Logger وconsole، انقر على سجلّ التنفيذ في أعلى أداة تعديل النصوص البرمجية.
عرض عمليات التنفيذ
لعرض سجلّ تنفيذ النص البرمجي، افتح مشروع برمجة تطبيقات وانقر على عمليات التنفيذ على يمين الشاشة.
لا توفّر لوحة عمليات التنفيذ سجلّات تتضمّن الطابع الزمني لمكالمات خدمة برمجة تطبيقات الفردية. استخدِم خدمة
console لإنشاء رسائل سجلات مناسبة. تظهر جميع السجلات التي تم إنشاؤها باستخدام
console في لوحة عمليات التنفيذ.
أمثلة على بنية V8
في ما يلي قائمة مختصرة بالميزات النحوية الشائعة المتاحة للنصوص البرمجية التي تستخدم وقت التشغيل V8.
let وconst
تتيح لك الكلمتان الرئيسيتان let وconst تحديد المتغيرات المحلية ذات نطاق الحظر والثوابت ذات نطاق الحظر، على التوالي.
// V8 runtime let s = "hello"; if (s === "hello") { s = "world"; console.log(s); // Prints "world" } console.log(s); // Prints "hello" const N = 100; N = 5; // Results in TypeError |
الدوال السهمية
توفّر دوال الأسهم طريقة مختصرة لتحديد الدوال ضمن التعبيرات.
// Rhino runtime function square(x) { return x * x; } console.log(square(5)); // Outputs 25 |
// V8 runtime const square = x => x * x; console.log(square(5)); // Outputs 25 // Outputs [1, 4, 9] console.log([1, 2, 3].map(x => x * x)); |
الدروس
توفّر الفئات طريقة لتنظيم الرموز البرمجية بشكل مفاهيمي باستخدام الوراثة. تُعد الفئات في V8 في الأساس بنية نحوية بسيطة لتسهيل عملية الوراثة المستندة إلى النموذج الأولي في JavaScript.
// V8 runtime class Rectangle { constructor(width, height) { // class constructor this.width = width; this.height = height; } logToConsole() { // class method console.log(`Rectangle(width=${this.width}, height=${this.height})`); } } const r = new Rectangle(10, 20); r.logToConsole(); // Outputs Rectangle(width=10, height=20) |
عمليات إسناد تفكيكية
توفّر تعبيرات تفكيك التعيين طريقة سريعة لتفكيك القيم من المصفوفات والكائنات إلى متغيرات مميزة.
// Rhino runtime var data = {a: 12, b: false, c: 'blue'}; var a = data.a; var c = data.c; console.log(a, c); // Outputs 12 "blue" var a = [1, 2, 3]; var x = a[0]; var y = a[1]; var z = a[2]; console.log(x, y, z); // Outputs 1 2 3 |
// V8 runtime const data = {a: 12, b: false, c: 'blue'}; const {a, c} = data; console.log(a, c); // Outputs 12 "blue" const array = [1, 2, 3]; const [x, y, z] = array; console.log(x, y, z); // Outputs 1 2 3 |
القيم الحرفية للنماذج
القيم الحرفية للنماذج هي قيم حرفية للسلاسل تسمح بالتعبيرات المضمَّنة. تتيح لك تجنُّب عبارات دمج السلاسل الأكثر تعقيدًا.
// Rhino runtime var name = 'Hi ' + first + ' ' + last + '.'; var url = 'http://localhost:3000/api/messages/' + id; |
// V8 runtime const name = `Hi ${first} ${last}.`; const url = `http://localhost:3000/api/messages/${id}`; |
المَعلمات التلقائية
تتيح لك المَعلمات التلقائية تحديد القيم التلقائية لمَعلمات الدالة في تعريف الدالة. يمكن أن يؤدي ذلك إلى تبسيط الرمز في نص الدالة لأنّه يزيل الحاجة إلى تعيين قيم تلقائية بشكل صريح للمَعلمات الناقصة.
// Rhino runtime function hello(greeting, name) { greeting = greeting || "hello"; name = name || "world"; console.log( greeting + " " + name + "!"); } hello(); // Outputs "hello world!" |
// V8 runtime const hello = function(greeting="hello", name="world") { console.log( greeting + " " + name + "!"); } hello(); // Outputs "hello world!" |
سلاسل متعددة الأسطر
يمكنك تحديد سلاسل متعددة الأسطر باستخدام بنية الجملة نفسها المستخدَمة في القيم الحرفية للنماذج. وكما هو الحال مع القيم الحرفية للنماذج، تتيح لك هذه البنية تجنُّب عمليات ربط السلاسل وتبسيط تعريفات السلاسل.
// Rhino runtime var multiline = "This string is sort of\n" + "like a multi-line string,\n" + "but it's not really one."; |
// V8 runtime const multiline = `This on the other hand, actually is a multi-line string, thanks to JavaScript ES6`; |
قيود وقت تشغيل V8
إنّ وقت التشغيل V8 في "برمجة تطبيقات Google" ليس بيئة عادية في Node.js أو المتصفح. ويمكن أن يؤدي ذلك إلى حدوث مشاكل في التوافق عند استدعاء مكتبات تابعة لجهات خارجية أو تعديل أمثلة الرموز البرمجية من بيئات JavaScript أخرى.
واجهات برمجة التطبيقات غير المتاحة
إنّ واجهات برمجة التطبيقات العادية التالية في JavaScript غير متاحة في وقت تشغيل V8 في Apps Script:
- المؤقتات:
setTimeoutوsetIntervalوclearTimeoutوclearInterval - قنوات البث:
ReadableStreamوWritableStreamوTextEncoderوTextDecoder - واجهات برمجة التطبيقات على الويب:
fetchوFormDataوFileوBlobوURLوURLSearchParamsوDOMExceptionوatobوbtoa - العملات المشفرة:
cryptoوSubtleCrypto - الكائنات العامة:
windowوnavigatorوperformanceوprocess(Node.js)
استخدِم واجهات برمجة التطبيقات التالية في "برمجة تطبيقات Google" كبدائل:
- الموقّتات: استخدِم
Utilities.sleepللتوقفات المتزامنة. لا يمكن استخدام المؤقتات غير المتزامنة. - الجلب: استخدِم
UrlFetchApp.fetch(url, params)لتقديم طلبات HTTP(S). - atob: استخدِم
Utilities.base64Decodeلفك ترميز السلاسل المرمّزة باستخدام Base64. - btoa: استخدِم
Utilities.base64Encodeلترميز السلاسل في Base64. - الترميز: استخدِموا
Utilitiesللدوال المتعلقة بالترميز، مثلcomputeDigestوcomputeHmacSha256SignatureوcomputeRsaSha256Signature.
بالنسبة إلى واجهات برمجة التطبيقات التي لا تتوفّر لها بدائل في "برمجة التطبيقات"، مثل TextEncoder، يمكنك في بعض الأحيان استخدام polyfill. إنّ polyfill هي مكتبة تنسخ وظائف واجهة برمجة التطبيقات غير المتاحة تلقائيًا في بيئة وقت التشغيل.
قبل استخدام polyfill، تأكَّد من توافقه مع وقت تشغيل V8 في Apps Script.
القيود المفروضة على العمليات غير المتزامنة
يتوافق وقت تشغيل V8 مع بنية async وawait والعنصر Promise.
ومع ذلك، فإنّ بيئة وقت التشغيل في "برمجة التطبيقات" متزامنة بشكل أساسي.
- المهام الصغيرة (متوافقة): تعالج بيئة التشغيل قائمة انتظار المهام الصغيرة (التي تحدث فيها عمليات معاودة الاتصال
Promise.thenوعمليات الحلawait) بعد إفراغ حزمة طلبات التنفيذ الحالية. - المهام الكبيرة (غير متوافقة): لا تتضمّن "برمجة تطبيقات Google" حلقة أحداث عادية للمهام الكبيرة. لا تتوفّر وظائف مثل
setTimeoutوsetInterval. - استثناء WebAssembly: واجهة برمجة تطبيقات WebAssembly هي الميزة المضمّنة الوحيدة التي تعمل بطريقة غير حظرية في وقت التشغيل، ما يتيح أنماط تجميع غير متزامن محدّدة (WebAssembly.instantiate).
جميع عمليات الإدخال والإخراج، مثل
UrlFetchApp.fetch، هي عمليات حظر. لتحقيق طلبات الشبكة المتوازية، استخدِم
UrlFetchApp.fetchAll.
القيود المفروضة على الصف
يفرض وقت تشغيل V8 قيودًا معيّنة على ميزات الفئات الحديثة ES6+:
- الحقول الخاصة: لا تتوافق حقول الفئات الخاصة (مثل
#field) مع هذه الميزة، وتتسبّب في حدوث أخطاء في التحليل. ننصحك باستخدام عمليات الإغلاق أوWeakMapلتغليف البيانات بشكل صحيح. - الحقول الثابتة: لا يمكن استخدام تعريفات الحقول الثابتة المباشرة ضمن نص الفئة (على سبيل المثال،
static count = 0;). خصِّص سمات ثابتة للفئة بعد تعريفها (على سبيل المثال،MyClass.count = 0;).
قيود الوحدات
- وحدات ES6: لا يتوافق وقت التشغيل V8 مع وحدات ES6 (
import/export). لاستخدام المكتبات، عليك استخدام آلية مكتبة "برمجة تطبيقات Google" أو تجميع الرمز البرمجي والتبعيات في ملف نص برمجي واحد. (أداة تتبُّع المشاكل) - ترتيب تنفيذ الملفات: يتم تنفيذ جميع ملفات النصوص البرمجية في مشروعك في نطاق عام. من الأفضل تجنُّب الرموز البرمجية ذات التأثيرات الجانبية على المستوى الأعلى والتأكّد من تعريف الدوال والفئات قبل استخدامها في جميع الملفات. رتِّب ملفاتك بشكل واضح في المحرّر إذا كانت هناك تبعيات بينها.
تفعيل وقت تشغيل V8
إذا كان النص البرمجي يستخدم وقت التشغيل Rhino، يمكنك التبديل إلى V8 باتّباع الخطوات التالية:
- افتح مشروع Apps Script.
- على يمين الصفحة، انقر على إعدادات المشروع .
- ضَع علامة في مربّع الاختيار تفعيل وقت تشغيل محرك V8 لمتصفِّح Chrome.
يمكنك بدلاً من ذلك تحديد وقت تشغيل النص البرمجي مباشرةً من خلال تعديل ملف بيان النص البرمجي:
- افتح مشروع Apps Script.
- على يمين الصفحة، انقر على إعدادات المشروع .
- ضَع علامة في مربّع الاختيار عرض ملف البيان "appsscript.json" في المحرر.
- على يمين الصفحة، انقر على أداة التعديل >
appsscript.json. - في ملف
appsscript.jsonmanifest، اضبط حقلruntimeVersionعلى القيمةV8. - في أعلى الصفحة، انقر على حفظ المشروع .
يوضّح المقال نقل النصوص البرمجية إلى V8 الخطوات الأخرى التي يجب اتّخاذها لضمان عمل النص البرمجي بشكل جيد باستخدام V8.
تفعيل وقت تشغيل Rhino
إذا كان النص البرمجي يستخدم V8 وكنت بحاجة إلى التبديل إلى وقت تشغيل Rhino الأصلي، اتّبِع الخطوات التالية:
- افتح مشروع Apps Script.
- على يمين الصفحة، انقر على إعدادات المشروع .
- أزِل العلامة من مربّع الاختيار تفعيل وقت تشغيل محرك V8 لمتصفِّح Chrome.
بدلاً من ذلك، عدِّل بيان النص البرمجي:
- افتح مشروع Apps Script.
- على يمين الصفحة، انقر على إعدادات المشروع .
- ضَع علامة في مربّع الاختيار عرض ملف البيان "appsscript.json" في المحرر.
- على يمين الصفحة، انقر على أداة التعديل >
appsscript.json. - في ملف
appsscript.jsonmanifest، اضبط حقلruntimeVersionعلى القيمةDEPRECATED_ES5. - في أعلى الصفحة، انقر على حفظ المشروع .
كيف يمكنني نقل النصوص البرمجية الحالية؟
يوضّح دليل نقل النصوص البرمجية إلى V8 الخطوات التي يجب اتّخاذها لنقل نص برمجي حالي لاستخدام V8. ويشمل ذلك تفعيل وقت تشغيل V8 والتحقّق من البرنامج النصي بحثًا عن أي حالات عدم توافق معروفة.
نقل النصوص البرمجية تلقائيًا إلى V8
اعتبارًا من 18 شباط (فبراير) 2020، ستنقل Google تدريجيًا النصوص البرمجية الحالية التي تجتاز اختبار التوافق المبرمَج إلى V8. وستستمر البرامج النصية المتأثرة في العمل بشكل طبيعي بعد نقل البيانات.
إذا أردت إيقاف النقل التلقائي لبرنامج نصي، اضبط قيمة الحقل
runtimeVersion
في ملف البيان على DEPRECATED_ES5. يمكنك اختيار نقل النص البرمجي إلى V8 يدويًا في أي وقت بعد ذلك.
كيف يمكنني الإبلاغ عن الأخطاء؟
يوضّح دليل الدعم كيفية الحصول على مساعدة في البرمجة على Stack Overflow، والبحث في تقارير المشاكل الحالية، والإبلاغ عن أخطاء جديدة، وتقديم طلبات للحصول على ميزات جديدة.