التزامن وتعدد الخيوط في JavaScript: من الألف إلى الياء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

التزامن وتعدد الخيوط في JavaScript: من الألف إلى الياء



تاريخياً، JavaScript هي لغة أحادية الخيط تعمل ضمن نموذج البرمجة الموجهة بالأحداث. ومع ذلك، تقدم JavaScript الحديثة (خاصة في بيئة Node.js) أدوات قوية للعمل مع التزامن وتعدد الخيوط. في هذه المقالة، سنشرح كيفية عمل Event Loop و Promises و async/await و Worker Threads والتجميع، وكيفية استخدام هذه الآليات لتحسين أداء تطبيقاتك.



1. Event Loop: أساس التزامن في JavaScript



Event Loop هو قلب النموذج غير المتزامن في JavaScript. يسمح بمعالجة العديد من العمليات دون حظر سلسلة التنفيذ الرئيسية. في Node.js، يدير Event Loop قوائم انتظار المهام (macrotasks و microtasks)، مما يوفر إدخال/إخراج غير محظور.



مثال على عمل Event Loop:



console.log('البداية');

setTimeout(() => { console.log('المؤقت 1');}, 0);

process.nextTick(() => { console.log('nextTick');});

Promise.resolve().then(() => { console.log('Promise');});

console.log('النهاية');

// الإخراج:// البداية// النهاية// nextTick// Promise// المؤقت 1


من المهم فهم ترتيب التنفيذ: الكود المتزامن ← microtasks (process.nextTick, Promise.then) ← macrotasks (setTimeout, setInterval).



2. Promises و async/await: إدارة التزامن



Promises هي كائنات تمثل نتيجة عملية غير متزامنة. تسمح بتجنب "callback hell" وبناء سلاسل استدعاءات. async/await هي سكر نحوي فوق Promises، مما يجعل الكود غير المتزامن يبدو وكأنه متزامن.



مثال مع async/await:



const fetchData = async (url) => {  const response = await fetch(url);  if (!response.ok) {    throw new Error(`خطأ HTTP: ${response.status}`);  }  return await response.json();};

const main = async () => { try { const data = await fetchData('https://api.example.com/data'); console.log('البيانات المستلمة:', data); } catch (error) { console.error('خطأ:', error.message); }};

main();


يسمح هذا الأسلوب بتنفيذ عدة عمليات غير متزامنة بالتوازي باستخدام Promise.all():



const [user, posts] = await Promise.all([  fetchUser(userId),  fetchPosts(userId)]);console.log(user, posts);


3. Worker Threads: تعدد خيوط حقيقي في Node.js



بدءاً من Node.js 10.5.0، توفر وحدة worker_threads إمكانية إنشاء خيوط حقيقية (threads) لتنفيذ المهام كثيفة الاستخدام لوحدة المعالجة المركزية (CPU). يعمل كل Worker في خيط منفصل مع مثيل V8 خاص به.



مثال على إنشاء Worker:



// main.jsconst { Worker } = require('worker_threads');

const runWorker = (workerData) => { return new Promise((resolve, reject) => { const worker = new Worker('./worker.js', { workerData });

worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) { reject(new Error(`تم إيقاف Worker بالرمز ${code}`)); } }); });};

const main = async () => { const result = await runWorker({ iterations: 1000000 }); console.log('النتيجة:', result);};

main();


// worker.jsconst { parentPort, workerData } = require('worker_threads');

const heavyComputation = (iterations) => { let result = 0; for (let i = 0; i < iterations; i++) { result += Math.sqrt(i); } return result;};

const result = heavyComputation(workerData.iterations);parentPort.postMessage(result);


تعتبر Worker Threads مثالية للمهام التي تحظر Event Loop: معالجة الصور، الحسابات الرياضية، تحليل الملفات الكبيرة.



4. التجميع: التوسع عبر عمليات متعددة

\

المدونات

توصيات الكتب