التزامن وتعدد الخيوط في TypeScript: المستوى المتقدم

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

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

ابدأ الدورة

التزامن وتعدد الخيوط في TypeScript: المستوى المتقدم



في تطوير الويب الحديث وتطبيقات الخادم باستخدام TypeScript، تصبح القدرة على العمل بكفاءة مع التزامن وتعدد الخيوط أمرًا بالغ الأهمية. على الرغم من أن JavaScript هي لغة أحادية الخيط، إلا أن بيئة التشغيل (المتصفح أو Node.js) توفر أدوات قوية لتنفيذ المهام بشكل متوازٍ. في هذه المقالة، سنستعرض التقنيات المتقدمة للعمل مع التزامن في TypeScript، بما في ذلك Worker Threads وSharedArrayBuffer وAtomics وأنماط التزامن.



1. الأساسيات الجوهرية: Event Loop و async/await



قبل الغوص في تعدد الخيوط، من المهم فهم كيفية عمل Event Loop في TypeScript. يتم تحقيق التزامن في بيئة أحادية الخيط من خلال الإدخال/الإخراج غير المحظور والعمليات غير المتزامنة.



لننظر إلى مثال باستخدام Promise.allSettled() للتنفيذ المتزامن لعدة مهام غير متزامنة مع معالجة الأخطاء:



interface TaskResult<T> {  status: 'fulfilled' | 'rejected';  value?: T;  reason?: Error;}

async function runConcurrentTasks<T>( tasks: Promise<T>[]): Promise<TaskResult<T>[]> { const results = await Promise.allSettled(tasks); return results.map(result => { if (result.status === 'fulfilled') { return { status: 'fulfilled', value: result.value }; } else { return { status: 'rejected', reason: result.reason }; } });}

// الاستخدامconst task1 = fetchData('/api/users');const task2 = fetchData('/api/posts');const task3 = fetchData('/api/comments');

const results = await runConcurrentTasks([task1, task2, task3]);


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



بالنسبة للمهام المكثفة لوحدة المعالجة المركزية (مثل معالجة الصور والتشفير والحسابات المعقدة)، هناك حاجة إلى خيوط حقيقية. في Node.js، يتم استخدام Worker Threads لهذا الغرض.



لنقم بإنشاء Worker مكتوب بلغة TypeScript:



// worker.tsimport { parentPort, workerData } from 'worker_threads';

interface WorkerInput { data: number[]; operation: 'sum' | 'multiply';}

interface WorkerOutput { result: number; duration: number;}

if (parentPort) { const input: WorkerInput = workerData; const start = performance.now(); let result: number; if (input.operation === 'sum') { result = input.data.reduce((acc, val) => acc + val, 0); } else { result = input.data.reduce((acc, val) => acc * val, 1); } const output: WorkerOutput = { result, duration: performance.now() - start }; parentPort.postMessage(output);}


الآن لنقم بإنشاء مدير لإدارة عدة Workers:



// threadPool.tsimport { Worker } from 'worker_threads';import path from 'path';

class ThreadPool<TInput, TOutput> { private workers: Worker[] = []; private taskQueue: Array<{ input: TInput; resolve: (value: TOutput) => void; reject: (reason?: any) => void; }> = [];

constructor( private workerScript: string, private poolSize: number = 4 ) { this.initialize(); }

private initialize(): void { for (let i = 0; i < this.poolSize; i++) { const worker = new Worker(this.workerScript); worker.on('message', (result: TOutput) => { const task = this.taskQueue.shift(); if (task) { task.resolve(result); } worker.postMessage(this.taskQueue[0]?.input); });

worker.on('error', (error) => { const task = this.taskQueue.shift(); if (task) { task.reject(error); } });

this.workers.push(worker); } }

async execute(input: TInput): Promise<TOutput> { return new Promise((resolve, reject) => { this.ta

المدونات

توصيات الكتب