البرمجة غير المتزامنة في TypeScript: دليل كامل عملي

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

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

ابدأ الدورة

البرمجة غير المتزامنة في TypeScript: دليل كامل عملي



تطوير الويب الحديث لا يمكن تصوره بدون العمليات غير المتزامنة: طلبات API، العمل مع قواعد البيانات، قراءة الملفات والمؤقتات. TypeScript، كإضافة فوق JavaScript، لا يحافظ فقط على جميع إمكانيات البرمجة غير المتزامنة، بل يضيف أيضًا كتابة صارمة للأنواع، مما يجعل الكود أكثر قابلية للتنبؤ وأمانًا. في هذا الدليل، سنناقش المفاهيم الأساسية لعدم التزامن في TypeScript - من Promise الأساسية إلى الأنماط المتقدمة - مع أمثلة كود حقيقية.



1. الأساسيات: Promise وكتابة الأنواع



Promise هو كائن يمثل نتيجة عملية غير متزامنة، يمكن أن تكتمل بنجاح (fulfilled) أو تُرفض (rejected). يسمح TypeScript بكتابة أنواع صارمة للقيمة التي سيعيدها Promise.



// مثال على Promise مكتوب النوعfunction fetchUserData(userId: number): Promise<{ name: string; email: string }> {  return new Promise((resolve, reject) => {    setTimeout(() => {      if (userId > 0) {        resolve({ name: 'إيفان إيفانوف', email: 'ivan@example.com' });      } else {        reject(new Error('معرف المستخدم غير صالح'));      }    }, 1000);  });}

// الاستخدامfetchUserData(1) .then(user => console.log(user.name)) // إيفان إيفانوف .catch(error => console.error(error.message));


لاحظ: Promise<{ name: string; email: string }> يضمن أننا في then سنحصل على كائن بهذه الحقول بالضبط. هذا يمنع الأخطاء المتعلقة بالخصائص غير المحددة.



2. Async/Await: السكر النحوي مع TypeScript



الكلمات المفتاحية async و await تجعل الكود غير المتزامن يبدو مثل الكود المتزامن، دون فقدان الأداء. يحدد TypeScript تلقائيًا نوع الإرجاع للدالة async على أنه Promise<T>.



// الدالة تعيد Promise<number>async function getDiscountPrice(price: number, discountPercent: number): Promise<number> {  if (discountPercent < 0 || discountPercent > 100) {    throw new Error('نسبة الخصم غير صحيحة');  }  // محاكاة حساب غير متزامن  const discount = await calculateDiscountAsync(price, discountPercent);  return price - discount;}

// دالة مساعدةfunction calculateDiscountAsync(price: number, percent: number): Promise<number> { return Promise.resolve(price * percent / 100);}

// الاستخدامasync function main() { try { const finalPrice = await getDiscountPrice(1000, 20); console.log(`السعر النهائي: ${finalPrice}`); // 800 } catch (error) { if (error instanceof Error) { console.error('خطأ:', error.message); } }}main();


هام: TypeScript لا يسمح باستخدام await خارج دالة async (باستثناء المستوى الأعلى في الوحدات ذات الإعدادات المحددة). قم دائمًا بتغليف الاستدعاءات في دالة async أو استخدم .then().



3. معالجة الأخطاء والأنماط المتقدمة



معالجة الأخطاء بشكل صحيح هي أساس الكود غير المتزامن الموثوق. يساعد TypeScript في اكتشاف الأخطاء في مرحلة التجميع، ولكن منطق المعالجة يجب كتابته يدويًا.



3.1. معالجة الأخطاء في async/await



async function safeFetchData(url: string): Promise<unknown> {  try {    const response = await fetch(url);    if (!response.ok) {      throw new Error(`خطأ HTTP! الحالة: ${response.status}`);    }    return await response.json();  } catch (error) {    // TypeScript يضيق النوع إلى Error    if (error instanceof Error) {      console.error('خطأ في الطلب:', error.message);      // يمكن إرجاع قيمة افتراضية أو إعادة رمي الخطأ      return null;    }    throw error; // خطأ غير معروف                

المدونات

توصيات الكتب