JavaScript

إتقان Async/Await في JavaScript

دليل شامل لفهم واستخدام async/await لكتابة كود غير متزامن أفضل.

٢ يونيو ٢٠٢٥
5 دقيقة قراءة
بواسطة useLines Team
JavaScriptAsyncPromisesES6
Illustration for إتقان Async/Await في JavaScript

البرمجة غير المتزامنة هي حجر الزاوية في تطوير الويب الحديث، مما يسمح للتطبيقات بالبقاء سريعة الاستجابة أثناء أداء العمليات التي تستغرق وقتًا طويلاً. تقدم صيغة async/await في JavaScript، التي تم تقديمها في ES2017، طريقة أنظف وأكثر سهولة للتعامل مع الكود غير المتزامن مقارنة بالاستدعاءات التقليدية أو سلاسل الوعد (.then() و .catch()).

فهم Async/Await

async/await هي مجرد سكر نحوي مبني فوق الوعود (Promises). إنها تجعل الكود غير المتزامن يبدو وكأنه كود متزامن، مما يجعله أسهل في القراءة والفهم.

الدوال غير المتزامنة (Async Functions):

يتم الإعلان عن دالة async باستخدام الكلمة الرئيسية async. إنها تعيد دائمًا وعدًا. إذا أعادت الدالة قيمة، فسيتم حل الوعد بهذه القيمة. إذا ألقت الدالة خطأ، فسيتم رفض الوعد بهذا الخطأ.

الكلمة الرئيسية Await:

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

الاستخدام الأساسي

إليك مثال بسيط على استخدام async/await لجلب البيانات من واجهة برمجة تطبيقات (API):

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Fetch error:', error);
  }
}

fetchData();

في هذا المثال:

  1. تم الإعلان عن دالة fetchData كـ async، مما يسمح باستخدام await بداخلها.
  2. توقف الكلمة الرئيسية await تنفيذ الدالة حتى يتم حل وعد fetch بكائن Response.
  3. نتحقق مما إذا كانت الاستجابة ناجحة. إذا لم تكن كذلك، فإننا نلقي خطأ سيتم التقاطه بواسطة كتلة catch.
  4. يتم استخدام الكلمة الرئيسية await مرة أخرى لانتظار حل وعد response.json() مع البيانات المحللة.
  5. يتم التقاط وتسجيل أي أخطاء أثناء عملية الجلب أو التحليل في كتلة catch.

معالجة الأخطاء باستخدام Try...Catch

يسمح استخدام كتل try...catch مع async/await بمعالجة أخطاء مباشرة بأسلوب متزامن، وهو ما يجده العديد من المطورين أنظف من كتل .catch() مع الوعود.

async function getUserData(userId) {
  try {
    const response = await fetch(`https://api.example.com/users/${userId}`);
    if (!response.ok) {
      throw new Error('User not found');
    }
    const user = await response.json();
    return user;
  } catch (error) {
    console.error('Error fetching user data:', error);
    throw error; // Re-throwing the error for further handling by the caller
  }
}

التنفيذ المتوازي مع Promise.all

عندما يكون لديك عدة عمليات غير متزامنة مستقلة، يمكنك تنفيذها بالتزامن باستخدام Promise.all. هذا أكثر كفاءة بكثير من انتظارها واحدة تلو الأخرى.

async function fetchMultipleData() {
  try {
    const [data1, data2, data3] = await Promise.all([
      fetch('https://api.example.com/data1').then(res => res.json()),
      fetch('https://api.example.com/data2').then(res => res.json()),
      fetch('https://api.example.com/data3').then(res => res.json())
    ]);
    console.log(data1, data2, data3);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
}

fetchMultipleData();

في هذا المثال، يتم بدء جميع طلبات الجلب الثلاثة في وقت واحد. يعيد Promise.all وعدًا واحدًا يتم حله عند حل جميع الوعود المدخلة. ثم توقف await الدالة مؤقتًا حتى يتم جلب جميع البيانات.

الأخطاء الشائعة التي يجب تجنبها

  1. نسيان استخدام await: إذا قمت باستدعاء دالة async بدون await، فستعيد وعدًا معلقًا بدلاً من القيمة المحلولة.
  2. عدم معالجة الأخطاء: قم دائمًا بتغليف استدعاءات await في كتل try...catch لمعالجة الرفض المحتمل للوعود. يمكن أن يؤدي رفض الوعود غير المعالج إلى تعطل تطبيقات Node.js.
  3. الاستخدام غير الفعال لـ await داخل الحلقات: سيؤدي استخدام await داخل حلقة for إلى التنفيذ التسلسلي، والذي يمكن أن يكون بطيئًا. إذا كانت العمليات لا تعتمد على بعضها البعض، فجمع كل الوعود في مصفوفة واستخدم Promise.all لتشغيلها بالتزامن.
  4. الإفراط في استخدام دوال async: قم فقط بالإعلان عن الدوال كـ async عندما تحتاج إلى استخدام await بداخلها. يمكن أن يؤدي الإفراط في الاستخدام إلى تعقيد غير ضروري ويجعل من الصعب التفكير في الكود الخاص بك.

من خلال فهم وتنفيذ هذه المفاهيم، يمكنك كتابة كود غير متزامن أنظف وأكثر قابلية للقراءة وأكثر كفاءة في JavaScript، مما يؤدي إلى أداء وصيانة أفضل في تطبيقاتك.

مقالات ذات صلة