الدرس الرابع عشر: البرمجة غير المتزامنة (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);
}
}
مقارنة بين الأدوات
الميزة | Callbacks | Promises | async/await |
---|---|---|---|
سهولة القراءة | ضعيفة | متوسطة | عالية |
إدارة الأخطاء | صعبة | أفضل | الأفضل |
قابلية الصيانة | منخفضة | جيدة | ممتازة |
الخاتمة
البرمجة غير المتزامنة هي أساس تطوير التطبيقات الحديثة، خصوصًا مع زيادة العمليات التي تعتمد على الشبكات أو التعامل مع البيانات. باستخدام الأدوات مثل Promises
و async/await
، يمكننا كتابة كود أكثر تنظيمًا وفعالية. ننصح باستخدام async/await
في المشاريع الحديثة لسهولة القراءة والتعامل مع الأخطاء.
اكتشاف المزيد من كود التطور
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.