شرح JavaScript Callback Function بأسلوب بسيط وواضح للمبتدئين
إذا كنت تتعلم JavaScript للمرة الأولى، فغالباً ستصادف سؤالاً مهماً: ما هي Callback Function؟ هذا المفهوم أساسي في فهم طريقة عمل الكثير من الأجزاء التفاعلية وغير المتزامنة في اللغة، لكنه قد يبدو معقداً عند شرحه بصيغة تقنية جافة. لذلك سنشرح الفكرة هنا بلغة واضحة، مع أمثلة عملية تساعدك على فهم سبب وجود callback functions وكيفية استخدامها بشكل صحيح.

ما هي الدالة في JavaScript؟
الدالة أو Function في JavaScript هي مجموعة من التعليمات البرمجية تنفّذ مهمة محددة. وجود هذه التعليمات داخل دالة يجعل الكود أكثر تنظيماً وقابلية لإعادة الاستخدام في أكثر من موضع داخل المشروع.
لنأخذ مثالاً بسيطاً: دالة تقوم بمضاعفة الرقم إذا كان زوجياً، وتعيده كما هو إذا لم يكن كذلك.
function doubleEven(n) {
if (n % 2 === 0) {
return n * 2;
}
return n;
}
يمكنك الآن استدعاء هذه الدالة كلما احتجت إلى هذا السلوك:
doubleEven(10); // Output: 20
doubleEven(5); // Output: 5
تمرير دالة كوسيط داخل دالة أخرى
في JavaScript لا يقتصر تمرير الوسائط على الأرقام أو النصوص فقط، بل يمكنك أيضاً تمرير Function كاملة إلى دالة أخرى. هذه من أقوى ميزات اللغة لأنها تمنحك مرونة كبيرة في التحكم بسلوك الدوال.
إليك مثالاً بسيطاً:
function foo(bar) {
bar();
}
في هذا المثال، تستقبل الدالة foo دالة أخرى باسم bar، ثم تقوم بتنفيذها داخل جسمها.
ولتشغيل ذلك عملياً:
foo(function() {
console.log('bar');
});
الناتج سيكون:
bar
لاحظ أننا مررنا دالة كاملة دون اسم، وتُسمى هذه Anonymous Function.
ما هي Callback Function في JavaScript؟
Callback Function هي ببساطة دالة يتم تمريرها كوسيط إلى دالة أخرى، بحيث يتم استدعاؤها لاحقاً عند حدوث أمر معيّن أو بعد انتهاء مهمة محددة.
المعنى العملي هنا هو: الدالة الأساسية تنفّذ عملاً ما، وعندما تنتهي، تقوم بإبلاغ الجهة التي استدعتها عبر تشغيل دالة أخرى. من هنا جاءت فكرة callback، أي “الرجوع للاستدعاء” أو “إعادة الإخطار”.
فهم الفكرة من خلال مثال واقعي
قصة Robin وطلب البيتزا
لفهم Callback Function بشكل أبسط، تخيّل السيناريو التالي:
طفل يُدعى Robin يحب البيتزا كثيراً. في أحد الأيام، فتح تطبيق PizzaHub وطلب نوعه المفضل. بعد تأكيد الطلب، أخبره التطبيق بأنه سيتم إشعاره عندما تصبح البيتزا جاهزة وفي طريقها إليه.
بعد مرور بعض الوقت، تصله رسالة تخبره بأن الطلب أصبح جاهزاً.

إذا حللنا هذا المشهد، فسنجد التسلسل التالي:
- Robin يطلب البيتزا.
- التطبيق يسجل الطلب.
- المطعم يبدأ التحضير.
- بعد الانتهاء، يتم إرسال إشعار إلى Robin.
هذا الإشعار هو جوهر فكرة Callback Function.
تحويل المثال الواقعي إلى كود JavaScript
لنفترض أن Robin قدّم الطلب بهذه الصورة:
orderPizza('Veg', 'Cheese Barbeque');
قد تكون الدالة الموجودة في الخادم مشابهة لهذا الشكل:
function orderPizza(type, name) {
console.log('Pizza ordered...');
console.log('Pizza is for preparation');
setTimeout(function() {
let msg = `Your ${type} ${name} Pizza is ready! The total bill is $13`;
console.log(`On the PizzaHub server ${msg}`);
}, 3000);
}
هنا نلاحظ أن setTimeout تمثل الوقت الذي يحتاجه المطعم لتحضير البيتزا. بعد 3 ثوانٍ يتم طباعة الرسالة.
لكن توجد مشكلة مهمة: الرسالة تظهر في جهة الخادم فقط، أما Robin نفسه فلن يعرف أن البيتزا أصبحت جاهزة. هنا نحتاج إلى آلية تُرسل الإشعار إلى الجهة التي طلبت التنفيذ.
كيف نستخدم Callback Function لحل المشكلة؟
الحل هو تعديل الدالة بحيث تستقبل callback function كوسيط إضافي. وبعد انتهاء التحضير، يتم استدعاء هذه الدالة وتمرير الرسالة إليها.
function orderPizza(type, name, callback) {
console.log('Pizza ordered...');
console.log('Pizza is for preparation');
setTimeout(function() {
let msg = `Your ${type} ${name} Pizza is ready! The total bill is $13`;
callback(msg);
}, 3000);
}
ثم يكون الاستدعاء بهذا الشكل:
orderPizza('Veg', 'Cheese Barbeque', function(message) {
console.log(message);
});
الآن، عندما تنتهي عملية التحضير، سيتم تشغيل الدالة المرسلة إلى orderPizza، وستصل الرسالة مباشرة إلى الطرف الذي طلب العملية.
لماذا تعتبر Callback Function مهمة؟
تكمن أهمية Callback Function في أنها تسمح للدوال بأن تكون أكثر مرونة وتفاعلية. بدلاً من كتابة كل شيء بشكل ثابت داخل دالة واحدة، يمكنك تحديد ما الذي يجب أن يحدث بعد انتهاء مهمة معينة.
أبرز الفوائد العملية
- تنفيذ كود مخصص بعد اكتمال مهمة معينة.
- التعامل مع العمليات غير المتزامنة مثل
setTimeoutوطلباتAPI. - فصل منطق التنفيذ عن منطق الاستجابة.
- إعادة استخدام الدوال بطريقة أكثر ذكاءً ومرونة.
متى تُستخدم Callback Functions غالباً؟
تظهر callback functions كثيراً في سيناريوهات برمجية شائعة، مثل:
- الانتظار حتى ينتهي تحميل البيانات من الخادم.
- تشغيل وظيفة عند نقر المستخدم على زر.
- تنفيذ إجراء بعد الانتهاء من قراءة ملف.
- معالجة نتيجة نجاح أو فشل مهمة معينة.
الفرق بين تمرير قيمة وتمرير دالة
| النوع | ما الذي يتم تمريره؟ | النتيجة |
|---|---|---|
| قيمة عادية | رقم أو نص أو Boolean | تستخدمها الدالة مباشرة |
| دالة | Function | يمكن تنفيذها لاحقاً عند الحاجة |
ملخص مفهوم Callback Function
- في JavaScript يمكن للدالة أن تستقبل دالة أخرى كوسيط.
- الدالة الممررة يمكن استدعاؤها لاحقاً بعد انتهاء مهمة أو عند تحقق شرط محدد.
- هذا النمط يُسمى Callback Function.
- يُستخدم كثيراً في البرمجة غير المتزامنة Asynchronous Programming.
ملاحظة مهمة: احذر من Callback Hell
على الرغم من أن callback functions مفيدة جداً، فإن الإفراط في استخدامها بشكل متداخل قد يؤدي إلى كود صعب القراءة والصيانة، وهو ما يُعرف باسم Callback Hell.
يحدث ذلك عندما تضع callback داخل callback داخل callback مرات كثيرة، فيصبح الكود معقداً ومربكاً. لهذا السبب ظهرت حلول أحدث في JavaScript مثل Promises و Async/Await.
الخلاصة التقنية
Callback Function ليست مجرد مصطلح نظري في JavaScript، بل هي فكرة أساسية لفهم كيفية تواصل الأجزاء المختلفة من البرنامج مع بعضها، خاصة عند وجود مهام تحتاج إلى وقت قبل أن تنتهي. إذا فهمت هذا المفهوم جيداً، فستكون مستعداً للانتقال بسهولة إلى مفاهيم أكثر تقدماً مثل Promises و Async/Await. من الناحية العملية، يمكن القول إن callbacks هي الخطوة الأولى لفهم البرمجة غير المتزامنة بشكل صحيح واحترافي.