البرمجة غير المتزامنة (Asynchronous Programming)

الدرس الرابع عشر: البرمجة غير المتزامنة (Asynchronous Programming) في JavaScript

مقدمة عن البرمجة غير المتزامنة

في البرمجة، هناك نوعان رئيسيان لمعالجة العمليات: البرمجة المتزامنة والبرمجة غير المتزامنة.

  • البرمجة المتزامنة (Synchronous Programming): يتم تنفيذ الأوامر خطوة بخطوة، بحيث يتم الانتقال من أمر إلى آخر بعد اكتمال السابق.
  • البرمجة غير المتزامنة (Asynchronous Programming): تسمح بتنفيذ أوامر متعددة بالتوازي، مما يجعل التطبيق أكثر كفاءة واستجابة، خاصة عند التعامل مع العمليات التي تستغرق وقتًا طويلًا مثل طلبات الشبكة أو القراءة من الملفات.

الفرق بين البرمجة المتزامنة وغير المتزامنة

البرمجة المتزامنة:

في هذا النمط، ينتظر التطبيق اكتمال كل مهمة قبل الانتقال إلى المهمة التالية.
مثال:

console.log("Start");
console.log("Processing...");
console.log("End");

الإخراج سيكون كما هو متوقع:

Start
Processing...
End

ولكن، ماذا لو كانت العملية الثانية تحتاج إلى وقت طويل؟
مثال:

console.log("Start");
for (let i = 0; i < 1e9; i++) {} // محاكاة عملية طويلة
console.log("Processing...");
console.log("End");

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

البرمجة غير المتزامنة:

في النمط غير المتزامن، يمكن للتطبيق تنفيذ المهام الأخرى أثناء انتظار المهام الطويلة.
مثال:

console.log("Start");
setTimeout(() => {
  console.log("Processing...");
}, 2000);
console.log("End");

الإخراج:

Start
End
Processing...

لاحظ كيف استمر البرنامج في العمل أثناء انتظار العملية غير المتزامنة.


أدوات البرمجة غير المتزامنة في JavaScript

1. مؤقتات JavaScript: setTimeout و setInterval

setTimeout

تُستخدم لتنفيذ دالة معينة بعد فترة زمنية محددة.

الصيغة:

setTimeout(callback, delay);
  • callback: الدالة التي سيتم تنفيذها.
  • delay: التأخير بالميلي ثانية.

مثال عملي:

console.log("Start");
setTimeout(() => {
  console.log("This runs after 3 seconds");
}, 3000);
console.log("End");
setInterval

تُستخدم لتكرار تنفيذ دالة معينة كل فترة زمنية محددة.

الصيغة:

setInterval(callback, interval);
  • interval: الفاصل الزمني بين التكرارات.

مثال عملي:

let count = 0;
const intervalId = setInterval(() => {
  count++;
  console.log(`Count: ${count}`);
  if (count === 5) {
    clearInterval(intervalId); // إيقاف التكرار
  }
}, 1000);

2. الدوال العكسية (Callbacks)

الدوال العكسية تُستخدم لتنفيذ التعليمات بعد اكتمال عملية معينة.
مثال:

function fetchData(callback) {
  setTimeout(() => {
    callback("Data loaded");
  }, 2000);
}

console.log("Start");
fetchData((data) => {
  console.log(data);
});
console.log("End");

الإخراج:

Start
End
Data loaded
مشاكل التداخل (Callback Hell):

عند تداخل العديد من الدوال العكسية، يصبح الكود معقدًا:

fetchData((data1) => {
  processData(data1, (data2) => {
    saveData(data2, (result) => {
      console.log("Saved:", result);
    });
  });
});

لهذا السبب، ظهرت الوعود (Promises) كحل.


3. الوعود (Promises)

الوعود توفر أسلوبًا أفضل للتعامل مع العمليات غير المتزامنة، حيث تجعل الكود أكثر تنظيمًا وقابلية للقراءة.

إنشاء وعد:
const myPromise = new Promise((resolve, reject) => {
  const success = true;
  if (success) {
    resolve("Operation succeeded");
  } else {
    reject("Operation failed");
  }
});
استخدام then و catch:
myPromise
  .then((message) => {
    console.log(message); // عند النجاح
  })
  .catch((error) => {
    console.error(error); // عند الفشل
  });
مثال عملي:
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Data fetched successfully");
    }, 2000);
  });
}

fetchData()
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });

4. async/await

async/await تُعتبر الطريقة الحديثة والأسهل للتعامل مع الوعود.

مثال عملي:
function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve("Data fetched successfully");
    }, 2000);
  });
}

async function main() {
  console.log("Start");
  const data = await fetchData(); // انتظار إكمال الوعد
  console.log(data);
  console.log("End");
}

main();

الإخراج:

Start
Data fetched successfully
End
التعامل مع الأخطاء:
async function main() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

مقارنة بين الأدوات

الميزةCallbacksPromisesasync/await
سهولة القراءةضعيفةمتوسطةعالية
إدارة الأخطاءصعبةأفضلالأفضل
قابلية الصيانةمنخفضةجيدةممتازة

الخاتمة

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


اكتشاف المزيد من كود التطور

اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.

اترك رد

Scroll to Top