عمال الويب في جافاسكريبت

عمال الويب في جافاسكريبت

تشرح هذه المقالة عمال الويب في جافاسكريبت۔

YouTube Video

javascript-web-worker.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>JavaScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    .container-flex {
 32        display: flex;
 33        flex-wrap: wrap;
 34        gap: 2em;
 35        max-width: 1000px;
 36        margin: 0 auto;
 37        padding: 1em;
 38        background-color: #ffffff;
 39        border: 1px solid #ccc;
 40        border-radius: 10px;
 41        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 42    }
 43
 44    .left-column, .right-column {
 45        flex: 1 1 200px;
 46        min-width: 200px;
 47    }
 48
 49    h1, h2 {
 50        font-size: 1.2rem;
 51        color: #007bff;
 52        margin-top: 0.5em;
 53        margin-bottom: 0.5em;
 54        border-left: 5px solid #007bff;
 55        padding-left: 0.6em;
 56        background-color: #e9f2ff;
 57    }
 58
 59    button {
 60        display: block;
 61        margin: 1em auto;
 62        padding: 0.75em 1.5em;
 63        font-size: 1rem;
 64        background-color: #007bff;
 65        color: white;
 66        border: none;
 67        border-radius: 6px;
 68        cursor: pointer;
 69        transition: background-color 0.3s ease;
 70    }
 71
 72    button:hover {
 73        background-color: #0056b3;
 74    }
 75
 76    #output {
 77        margin-top: 1em;
 78        background-color: #1e1e1e;
 79        color: #0f0;
 80        padding: 1em;
 81        border-radius: 8px;
 82        min-height: 200px;
 83        font-family: Consolas, monospace;
 84        font-size: 0.95rem;
 85        overflow-y: auto;
 86        white-space: pre-wrap;
 87    }
 88
 89    .highlight {
 90        outline: 3px solid #ffc107; /* yellow border */
 91        background-color: #fff8e1;  /* soft yellow background */
 92        transition: background-color 0.3s ease, outline 0.3s ease;
 93    }
 94
 95    .active {
 96        background-color: #28a745; /* green background */
 97        color: #fff;
 98        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 99        transition: background-color 0.3s ease, box-shadow 0.3s ease;
100    }
101  </style>
102</head>
103<body>
104    <div class="container">
105        <h1>JavaScript Console</h1>
106        <button id="executeBtn">Execute</button>
107        <div id="output"></div>
108    </div>
109
110    <script>
111        // Override console.log to display messages in the #output element
112        (function () {
113            // Override console.log
114            const originalLog = console.log;
115            console.log = function (...args) {
116                originalLog.apply(console, args);
117                const message = document.createElement('div');
118                message.textContent = args.map(String).join(' ');
119                output.appendChild(message);
120            };
121
122            // Override console.error
123            const originalError = console.error;
124            console.error = function (...args) {
125                originalError.apply(console, args);
126                const message = document.createElement('div');
127                message.textContent = args.map(String).join(' ');
128                message.style.color = 'red'; // Color error messages red
129                output.appendChild(message);
130            };
131        })();
132
133        document.getElementById('executeBtn').addEventListener('click', () => {
134            // Prevent multiple loads
135            if (document.getElementById('externalScript')) return;
136
137            const script = document.createElement('script');
138            script.src = 'javascript-web-worker.js';
139            script.id = 'externalScript';
140            //script.onload = () => console.log('javascript-web-worker.js loaded and executed.');
141            //script.onerror = () => console.log('Failed to load javascript-web-worker.js.');
142            document.body.appendChild(script);
143        });
144    </script>
145</body>
146</html>

Web Worker في JavaScript

عامل الويب في جافاسكريبت هو آلية تتيح تشغيل الشيفرة في مسار منفصل عن المسار الرئيسي۔ يسمح هذا بإجراء الحسابات الثقيلة والعمليات طويلة الأمد بشكل غير متزامن، مما يمنع حظر السلسلة الرئيسية۔ باستخدام Web Worker، تتحسن استجابة واجهة المستخدم ويتحسن أداء التطبيق.۔

الاستخدام الأساسي لـWeb Worker

دعونا نلقي نظرة على الاستخدام الأساسي لعامل الويب۔

يتم إنشاء عامل ويب جديد من خلال تحديد ملف جافاسكريبت۔

1// worker.js (created as a separate file)
2onmessage = function(event) {
3    // Receive a message
4    const data = event.data;
5    // Perform heavy computation or processing
6    const result = data * 2;
7    // Return the result to the main thread
8    postMessage(result);
9};
 1// Main thread (main.js)
 2const worker = new Worker('worker.js');
 3
 4// Send a message to the worker
 5worker.postMessage(10);
 6
 7// Receive a message from the worker
 8worker.onmessage = function(event) {
 9    console.log('Result from Worker: ', event.data); // Result: 20
10};
11
12// Error handling
13worker.onerror = function(error) {
14    console.error('Worker error: ', error);
15};
  • يوضح هذا الكود الآلية الأساسية لاستخدام عامل الويب لطلب العمليات الحسابية من المسار الرئيسي واستلام النتائج بشكل غير متزامن۔ يرسل الرقم 10 كرسالة إلى عامل الويب ويتلقى الرقم 20 كرسالة نتيجة۔ يتواصل المسار الرئيسي مع عامل الويب من خلال إرسال واستقبال الرسائل لطلب واستلام نتائج المعالجة۔

الوظائف الأساسية

يقدم عامل الويب الميزات الأساسية التالية۔

  • postMessage و onmessage تُستخدم لإرسال واستقبال الرسائل بين المسار الرئيسي وعامل الويب۔ أرسل البيانات باستخدام postMessage واستقبلها باستخدام onmessage۔
  • استقلالية المسارات يعمل عامل الويب بشكل مستقل تمامًا عن المسار الرئيسي۔ لذلك، لا يمكن الوصول إلى المتغيرات والوظائف المعرفة في السلسلة الرئيسية۔ يجب تمرير البيانات المطلوبة عبر postMessage۔
  • استيراد السكريبت لتحميل السكريبتات الخارجية داخل عامل الويب، استخدم importScripts()۔
1// mathUtils.js
2function double(n) {
3    return n * 2;
4}
1// worker.js
2importScripts('mathUtils.js');
3
4onmessage = function(event) {
5    const input = event.data;
6    const result = double(input); // mathUtils.jsの関数を使用
7    postMessage(result);
8};
 1// Main thread (main.js)
 2const worker = new Worker('worker.js');
 3
 4// Send a message to the worker
 5worker.postMessage(10);
 6
 7// Receive a message from the worker
 8worker.onmessage = function(event) {
 9    console.log('Result from Worker: ', event.data); // Result: 20
10};
11
12// Error handling
13worker.onerror = function(error) {
14    console.error('Worker error: ', error);
15};

بدلاً من ذلك، يمكنك أيضًا استخدام import كما هو موضح أدناه۔

1// lib.js
2
3// Simulated CPU-intensive task
4export function doHeavyWork(n) {
5    return n * 2;
6}
1// worker.js
2import { doHeavyWork } from './lib.js';
3
4self.onmessage = (event) => {
5  const data = event.data;
6  const result = doHeavyWork(data);
7  self.postMessage(result);
8};
 1// Main thread (main.js)
 2const worker = new Worker('worker.js', { type: 'module' });
 3
 4// Send a message to the worker
 5worker.postMessage(10);
 6
 7// Receive a message from the worker
 8worker.onmessage = function(event) {
 9    console.log('Result from Worker: ', event.data); // Result: 20
10};
11
12// Error handling
13worker.onerror = function(error) {
14    console.error('Worker error: ', error);
15};
  • من خلال تحديد type: 'module' في معامل new Worker، يمكنك التعامل مع العامل كوحدة ES واستخدام بنية import۔

الاختلافات بين Web Worker ووظائف async

Web Worker

الميزات
  • عزل المسارات ينفذ عامل الويب الكود الخاص بجافاسكريبت في مسار منفصل۔ يسمح هذا بتنفيذ المعالجة الحسابية الثقيلة دون حظر الخيط الرئيسي (خيط واجهة المستخدم).۔
  • المعالجة المتزامنة/المتعددة يتيح استخدام عامل الويب برامج جافاسكريبت لتنفيذ المعالجة المتزامنة في عدة مسارات۔
  • التواصل عبر الرسائل لا يشارك عامل الويب والمسار الرئيسي البيانات بشكل مباشر، بل يتبادلان الرسائل باستخدام postMessage و onmessage۔
  • لا يمكن الوصول إلى واجهة المستخدم لا يستطيع عامل الويب الوصول إلى الـDOM، لذلك لا يمكنه التلاعب مباشرة بواجهة المستخدم۔
حالات الاستخدام
  • إنه مناسب لعمليات الحساب الثقيلة مثل معالجة الصور، وتحليل البيانات، والتشفير.۔
  • يمكن استخدامه عندما لا تريد حظر الخيط الرئيسي.۔

async

الميزات
  • تبسيط المعالجة غير المتزامنة دالة async هي بنية لجعل المعالجة غير المتزامنة أكثر قابلية للقراءة، وتستخدم Promise داخليًا۔
  • مسار واحد فقط جميع دوال async تعمل على المسار الرئيسي۔ لذلك، تحتاج إلى ابتكار طرق لتجنب حظر خيط واجهة المستخدم.۔
  • مثالي لعمليات الإدخال والإخراج هو مناسب للمهام غير المتزامنة مثل الاتصال بالشبكة وقراءة الملفات، ولكنه غير مناسب للعمليات الحسابية الثقيلة۔
حالات الاستخدام
  • هو مناسب للاتصالات الشبكية مثل استدعاءات API۔
  • هو مناسب لقراءة وكتابة الملفات باستخدام واجهات برمجة تطبيقات المتصفح أو Node.js۔

الاختلافات الرئيسية

الميزات Web Worker async
بيئة التنفيذ سلسلة عمليات منفصلة السلسلة الرئيسية
الغرض معالجة موازية، تخفيف عبء العمليات الثقيلة وصف مختصر للعمليات غير المتزامنة
الوصول إلى DOM غير ممكن ممكن
طريقة الاتصال تمرير الرسائل (مثل postMessage) غير مطلوبة (تُدار عبر استدعاءات الدوال المباشرة أو استخدام await)
حالات الاستخدام العمليات التي تستغرق وقتاً طويلاً، تحليل البيانات عمليات الإدخال/الإخراج، استدعاءات API

متى يتم استخدام كل منهما

للعمليات التي تستهلك وحدة المعالجة المركزية بكثافة، يمكنك استخدام Web Worker لتقليل العبء على السلسلة الرئيسية۔ من ناحية أخرى، بالنسبة للاتصالات بالشبكة أو عمليات الإدخال/الإخراج، يمكنك تبسيط الكود الخاص بك باستخدام async/await۔

من خلال الجمع بين الاثنين بشكل مناسب، يمكنك تحقيق معالجة غير متزامنة بكفاءة۔

أمثلة على استخدام Web Worker

مثال على نقل العمليات الحسابية الثقيلة

التالي هو مثال على تفويض العمليات الحسابية الثقيلة۔

 1// worker.js
 2onmessage = function(event) {
 3    const num = event.data;
 4    const result = fibonacci(num);
 5    postMessage(result);
 6};
 7
 8function fibonacci(n) {
 9    if (n <= 1) return n;
10    return fibonacci(n - 1) + fibonacci(n - 2);
11}
1// Main thread
2const worker = new Worker('worker.js');
3
4worker.onmessage = function(event) {
5    console.log('Fibonacci result: ', event.data);
6};
7
8worker.postMessage(40); // Delegate heavy computation to the worker
  • هذا الكود هو مثال على استخدام عامل الويب لفصل وتنفيذ المهام الثقيلة مثل حساب متتالية فيبوناتشي بعيدًا عن الخيط الرئيسي۔

مثال على تحديد اسم المهمة

التالي هو مثال على إرسال واستقبال الرسائل عن طريق تحديد اسم المهمة۔

 1// worker.js
 2self.onmessage = function(event) {
 3    switch (event.data.task) {
 4        case 'add':
 5            const result = event.data.a + event.data.b;
 6            self.postMessage({ task: 'result', value: result });
 7            break;
 8        default:
 9            self.postMessage({ task: 'error', message: 'Invalid Task' });
10    }
11};
 1// Main thread
 2const worker = new Worker('worker.js');
 3
 4worker.onmessage = function(event) {
 5    switch (event.data.task) {
 6        case 'result':
 7            console.log('Task result: ', event.data.value);
 8            break;
 9        case 'error':
10            console.error('Error: ', event.data.message);
11            break;
12    }
13};
14
15worker.postMessage({ task: 'add', a: 10, b: 20 });
  • هذا الكود هو مثال على توزيع المعالجة بناءً على اسم المهمة في الرسالة، حيث يقوم عامل الويب بإرجاع نتائج الحسابات أو الأخطاء إلى الخيط الرئيسي مع اسم المهمة۔

ملاحظات

عند استخدام عامل الويب، ضع في اعتبارك النقاط التالية۔

  • لا يمكنه الوصول إلى الـDOM لا يمكن لعامل الويب التلاعب بواجهة المستخدم أو الوصول إلى الـDOM۔ يجب تنفيذ التعامل مع DOM في السلسلة الرئيسية۔
  • عبء التواصل هناك بعض العبء عند تبادل البيانات بين المسار الرئيسي وعامل الويب۔ يمكن أن يؤثر ذلك على الأداء، خاصة عند تبادل كميات كبيرة من البيانات بشكل متكرر۔
  • سياسة نفس الأصل سكريبتات عامل الويب خاضعة لسياسة نفس الأصل۔ لا يمكن تحميل النصوص البرمجية من نطاقات مختلفة۔

يمكن لاستخدام Web Worker تحسين أداء واستجابة تطبيقك، ولكن من المهم استخدامه بشكل مناسب مع مراعاة القيود مثل عدم القدرة على التلاعب بـ DOM۔

يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔

YouTube Video