الدالة ‎‎jQuery.Callbacks()‎‎ في jQuery

من موسوعة حسوب
< jQuery‏ | jQuery
اذهب إلى: تصفح، ابحث

jQuery.Callbacks( flags )‎

القيم المعادة

تعيد كائن ردود النداء Callbacks.

الوصف

تعيد هذه الدالة كائنًا مُتعدِّد الأغراض يُزوِّدنا بطريقة فعَّالة لإدارة قائمة ردود النداء.

jQuery.Callbacks( flags )‎

أُضيف مع الإصدار: 1.7.

flags

سلسلة نصية تمثل قائمة اختياريَّة من عدِّة رايات (flags) مفصولةٍ بفراغٍ تسهم في تغيير كيفيَّة سلوك قائمة ردود النداء.

تُستخدَم الدالة ‎$.Callbacks()‎ داخليًّا لتأمين الوظائف الأساسيَّة التي يحتاجها المكونين ‎$.ajax()‎ و ‎$.Deferred()‎ في jQuery. يمكن أن تُستخدَم كقاعدة متجانسة لتعريف وظائف العناصر الجديدة.

تدعم الدالة ‎$.Callbacks()‎ عددًا من التوابع منها التابع callbacks.add()‎، والتابع callbacks.remove()‎، والتابع callbacks.fire()‎، والتابع callbacks.disable()‎ (ارجع إلى صفحة كائن ردود النداء callbacks للاطلاع على قائمة التوابع المدعومة الكاملة).

الشيفرة التالية تحتوي على نموذج لتابعين أحدهما يدعى fn1 والآخر يدعى fn2:
function fn1( value ) {
  console.log( value );
}
 
function fn2( value ) {
  console.log( "يقول fn2: " + value );
  return false;
}
يمكن أن نضيف هذين التابعين إلى القائمة ‎$.Callbacks كردود نداء ثم نستدعيهما كما يلي:
var callbacks = $.Callbacks();
callbacks.add( fn1 );
 
// ستظهر النتيجة: مرحبًا
callbacks.fire( "مرحبًا" );
 
callbacks.add( fn2 );
 
// أهلًا :fn2 ستظهر النتيجة: مرحبًا، يقول
callbacks.fire( "أهلًا" );
الخلاصة هي أنَّه أصبح من الممكن إنشاء قوائم معقَّدة لردود النداء ببساطة، إذ يمكن حينها تمرير القيم المدخلة عبر عدد من الدوال بقدر ما نحتاج بكل سهولة.

استُخدِم في هذا المثال تابعان هما: التابع ‎.add()‎، والتابع ‎.fire()‎؛ يدعم التابع ‎.add()‎ إضافة ردود نداء جديدة إلى قائمة ردود النداء، بينما ينفِّذ التابع ‎.fire()‎ الدوال المضافة مع توفير وسيلةٍ لتمرير الوسائط المعطاة لكي تعالجها ردود النداء في القائمة نفسها.

هنالك تابع آخر تدعمه الدالة ‎$.Callbacks وهو التابع ‎.remove()‎ الذي يملك القدرة على حذف رد نداءٍ محدَّد من قائمة ردود النداء. إليك هذا المثال الذي يوضح كيفيَّة استعمال هذا التابع:
var callbacks = $.Callbacks();
callbacks.add( fn1 );
 
// ستظهر النتيجة: مرحبًا
callbacks.fire( "مرحبًا" );
 
callbacks.add( fn2 );
 
// أهلًا :fn2 ستظهر النتيجة: مرحبًا، يقول
callbacks.fire( "أهلًا" );
 
callbacks.remove( fn2 );
 
// fn2 ستظهر النتيجة: مرحبًا مجددًا، إذ قد حذف
callbacks.fire( "مرحبًا مجددًا" );

الرايات المدعومة (supported flags)

الوسيط flags هو وسيط اختياري يُمرَّر إلى الدالة ‎$.Callbacks()‎ ويتألف من سلسلة نصية تمثِّل قائمةً من عدِّة رايات مفصولةٍ بفراغٍ تسهم في تغيير كيفيَّة سلوك قائمة ردود النداء (مثل ‎$.Callbacks( "unique stopOnFalse" )‎).

الرايات الممكن استعمالها هي:

  • once: التأكد من أنَّ قائمة دوال النداء يمكن أن تُطلَق مرةً واحدةً فقط (مثل Deferred).
  • memory: استمرار تتبع القيم السابقة واستدعاء أي رد نداء يضاف بعد إطلاق قائمة ردود النداء مباشرةً مع استعمال أحدث القيم المخزَّنة (مثل Deferred).
  • unique: التأكد من إضافة رد النداء مرةً واحدةً فقط (لذا لا توجد أية قيم مكررة في القائمة).
  • stopOnFalse: مقاطعة الاستدعاءات عندما يعيد رد النداء القيمة false.

ستسلك قائمة ردود النداء افتراضيًّا سلوكًا مماثلًا لقائمة ردود نداء الأحداث ويمكن إطلاقها مرات عديدة.

تفحَّص الأمثلة التالية لمعرفة كيفيَّة استعمال الوسيط flags بشكل صحيح:

  • $.Callbacks( "once" )‎
var callbacks = $.Callbacks( "once" );
callbacks.add( fn1 );
callbacks.fire( "مرحبًا" );
callbacks.add( fn2 );
callbacks.fire( "أهلًا" );
callbacks.remove( fn2 );
callbacks.fire( "مرحبًا مجددًا" );
 
/*
ستظهر النتيجة:
مرحبًا
*/
  • ‎$.Callbacks( "memory" )‎:
var callbacks = $.Callbacks( "memory" );
callbacks.add( fn1 );
callbacks.fire( "مرحبًا" );
callbacks.add( fn2 );
callbacks.fire( "أهلًا" );
callbacks.remove( fn2 );
callbacks.fire( "كيف الحال" );
 
/*
ستظهر النتيجة:
مرحبًا
مرحبًا :fn2 يقول
أهلًا
أهلًا :fn2 يقول
مرحبًا مجددًا
*/
  • $.Callbacks( "unique" )‎:
var callbacks = $.Callbacks( "unique" );
callbacks.add( fn1 );
callbacks.fire( "مرحبًا" );
callbacks.add( fn1 ); // إضافته مرة أخرى
callbacks.add( fn2 );
callbacks.fire( "أهلًا" );
callbacks.remove( fn2 );
callbacks.fire( "مرحبًا مجددًا" );
 
/*
ستظهر النتيجة:
مرحبًا
أهلًا
أهلًا :fn2 يقول
مرحبًا مجددًا
*/
  • $.Callbacks( "stopOnFalse" )‎:
function fn1( value ) {
  console.log( value );
  return false;
}
 
function fn2( value ) {
  fn1( "يقول fn2: " + value );
  return false;
}
 
var callbacks = $.Callbacks( "stopOnFalse" );
callbacks.add( fn1 );
callbacks.fire( "مرحبًا" );
callbacks.add( fn2 );
callbacks.fire( "أهلًا" );
callbacks.remove( fn2 );
callbacks.fire( "مرحبًا مجددًا" );
 
/*
ستظهر النتيجة:
مرحبًا
أهلًا
مرحبًا مجددًا
*/
بما أنَّ ‎$.Callbacks()‎ تدعم قائمة من الرايات عوضًا عن رايةٍواحدة، فإنَّ تعيين عدة رايات في آنٍ واحدٍ له تأثير تراكمي مشابه لتأثير "&&". أي من الممكن الدمج بين الرايات لإنشاء قائمة ردود نداء فريدة والتأكد من أنَّ القائمة قد أُطلقت مسبقًا، ويؤدي إضافة المزيد من ردود النداء إلى استدعائها مع أحدث القيم المُطلَقَة (مثل استعمال ‎$.Callbacks("unique memory")‎).
  • ‎$.Callbacks( 'unique memory' )‎:
function fn1( value ) {
  console.log( value );
  return false;
}
 
function fn2( value ) {
  fn1( "يقول fn2: " + value );
  return false;
}
 
var callbacks = $.Callbacks( "unique memory" );
callbacks.add( fn1 );
callbacks.fire( "مرحبًا" );
callbacks.add( fn1 ); // إضافته مرة أخرى
callbacks.add( fn2 );
callbacks.fire( "أهلًا" );
callbacks.add( fn2 );
callbacks.fire( "كيف الحال" );
callbacks.remove( fn2 );
callbacks.fire( "الحمد لله" );
 
/*
ستظهر النتيجة:
مرحبًا
مرحبًا :fn2 يقول
أهلًا
أهلًا :fn2 يقول
كيف الحال
كيف الحال :fn2 يقول
الحمد لله
*/
دمج الرايات مع ‎$.Callbacks()‎ مدعومٌ داخليًّا في jQuery للدالة ‎.done()‎ والدالة ‎.fail()‎ في الكائن المؤجَّل Deferred، إذ يستعمل كلاهما ‎$.Callbacks('memory once')‎. يمكن أيضًا فك ارتباط توابع ‎$.Callbacks، وتصبح الحاجة لذلك مُلحَّةً عندما تحتاج إلى تعريف إصدارات مختزلة للسهولة:
var callbacks = $.Callbacks(),
  add = callbacks.add,
  remove = callbacks.remove,
  fire = callbacks.fire;
 
add( fn1 );
fire( "مرحبًا يا صديق" );
remove( fn1 );

التابع ‎$.Callbacks والتابع ‎$.Deferred، والنشر/الاشتراك

الفكرة العامة القابعة خلف النشر/الاشتراك (pub/sub أو نمط المراقبة) هي تعزيز الاقتران الرخو (loose coupling) في التطبيقات. فبدلًا من استدعاء كائنات وحيدة مع توابع لكائنات أخرى، يشترك كائنٌ بمهمة أو نشاط محدَّد لكائن آخر ويُنبَّه عندما يحدث ذلك. المراقبون يُدعَون أيضًا بأنَّهم مشتركون، ونشير إلى الكائن المُراقِب على أنَّه ناشر (Publisher أو الفاعل [subject])؛ فيُنبِّه الناشرون المشتركين عند وقوع الأحداث.

لإظهار إمكانيات مكوِّن الإنشاء (component-creation) للدالة ‎$.Callbacks()‎، يمكن تنفيذ نظام النشر/الاشتراك باستعمال قوائم ردود النداء فقط. عند استعمال ‎$.Callbacks كصفوف (topics) في الطابور، يمكن أن يُنفَّذ نظامٌ للنشر والاشتراك بتلك الصفوف كما موضَّح في الشيفرة التالية:
var topics = {};
 
jQuery.Topic = function( id ) {
  var callbacks, method,
    topic = id && topics[ id ];
 
  if ( !topic ) {
    callbacks = jQuery.Callbacks();
    topic = {
      publish: callbacks.fire,
      subscribe: callbacks.add,
      unsubscribe: callbacks.remove
    };
    if ( id ) {
      topics[ id ] = topic;
    }
  }
  return topic;
};
يمكن استخدام هذه الشيفرة لتكون جزءًا من تطبيقك للنشر والاشتراك بالأحداث التي تريدها بسهولة كبيرة:
// مشتركون
$.Topic( "mailArrived" ).subscribe( fn1 );
$.Topic( "mailArrived" ).subscribe( fn2 );
$.Topic( "mailSent" ).subscribe( fn1 );
 
// ناشرون
$.Topic( "mailArrived" ).publish( "مرحبًا يا صديق" );
$.Topic( "mailSent" ).publish( "رائع! إنه بريد" );
 
// fn2 و fn1 هنا، تُدفَع "مرحبًا يا صديق" إلى  
// "mailArrived" عندما ينشر التنبيه
// fn1 تُدفَع أيضًا العبارة "رائع! إنه بريد" إلى
//"mailSent" عندما ينشر التنبيه 
 
/*
ستظهر النتيجة::
مرحبًا يا صديق
مرحبًا يا صديق :fn2 يقول: hello world!
رائع! إنه بريد
*/
ستجد أنَّ هذا مفيدٌ ويمكن الوصول إلى حدود أبعد مما تتخيل. فباستعمال ‎$.Deferreds، يمكن التأكد من أنَّ الناشرين ينشرون التنبيهات للمشتركين فقط حالما تكتمل مهام معيَّنة (تكون مقبولة [resolved]). تَفحَّص الشيفرة التالية التي تعدُّ نموذجًا يشرح كيفيَّة تطبيق هذا الأمر:
// mailArrived الاشتراك بالتنبيهات
$.Topic( "mailArrived" ).subscribe( fn1 );
 
// Deferreds إنشاء نسخة جديدة من الكائن
var dfd = $.Deferred();
 
// دون النشر بشكل مباشرة topic تعريف صف
var topic = $.Topic( "mailArrived" );
 
// عندما يقبل الكائن المؤجل، تنشر 
// تنشر التنبيهات إلى المشتركين
dfd.done( topic.publish );
 
// الكائن المؤجل الذي بصدد قبوله مع رسالة
// سيعاد إرسال هذه الرسالة إلى المشتركين. من الممكن دمج هذا 
// ليكتمل) وبذلك Ajax السلوك بسهولة مع نمط أكثر تعقيدًا (مثل انتظار استدعاء
// تُنشَر الرسائل عندما تنتهي المهمة فعليًّا فقط
dfd.resolve( "لقد نشرت الرسالة" );

مصادر