التابع jQuery.when()
في jQuery
jQuery.when( deferreds )
القيم المعادة
يعيد كائنًا من النوع Promise.
الوصف
يوفِّر هذا التابع طريقةً لتنفيذ دوال ردود النداء بناءً على حالة الكائنات Thenable الممرَّرة إليها (من الممكن أن لا يمرَّر أيُّ كائن أيضًا)، ويمرَّر عادةً كائنات من النوع Deferred عوضًا عنها التي تمثل أحداثًا غير متزامنة.
jQuery.when( deferreds )
أُضيف مع الإصدار: 1.5.
deferreds
كائنً من النوع Deferred أو Promise أو Thenable.
إن لم تعطَ قيمة الوسيط deferreds
، فسيعيد التابع jQuery.when()
الكائن Promise بحالة "مقبول".
إن مُرِّر كائن واحد من النوع Deferred، فسيعيد التابع الكائن Promise الخاص به (مجموعةٌ فرعيَّةٌ من توابع Deferred). يمكن استدعاء توابع إضافيَّة للكائن Deferred لربط دوال ردود نداء، مثل التابع deferred.then
. عندما "يُقبل" أو "يُرفَض" الكائن المؤجَّل Deferred -عادةً من طرف الشيفرة التي أنشأته من البداية-،فسيُستدعَى رد النداء الملائم حينئذٍ. على سبيل المثال، الكائن jqXHR التي تعيده الدالة jQuery.ajax() هو كائنٌ متوافقٌ مع الكائن Promise ويمكن استعماله بهذه الطريقة:
$.when( $.ajax( "test.aspx" ) ).then(function( data, textStatus, jqXHR ) {
alert( jqXHR.status ); // 200
});
إن مُرِّر إلى التابع jQuery.when()
كائن وحيد ولم يكن هذا الكائن من النوع Deferred أو Promise، فسيعامل حينئذٍ على أنَّه كائن Deferred مقبول وستنفَّذ أيَّة دوال ردود نداء أضيفت باستعمال deferred.done()
(تُدعى doneCallbacks) مباشرةً، إذ سيُمرَّر إليها قيمة الكائن المقبول. في هذه الحالة وبما أنَّ الكائن Deferred لن يرفض مُطلقًا، لن تستدعى أيَّة دوال ردود نداء أضيفت باستعمال deferred.fail()
. تفحَّص الشيفرة التالية مثلًا التي تشرح ذلك:
$.when( { testing: 123 } ).done(function( x ) {
alert( x.testing ); // "123"
});
إن لم يُمرَّر إلى التابع jQuery.when()
أي وسيط، فسيعيد كائنًا من النوع Promise مقبول:
$.when().then(function( x ) {
alert( "سأُستدعَى أنا مباشرةً" );
});
أمَّا إن مُرِّر إلى التابع jQuery.when()
عدَّة كائنات Deferred، فسيفترض التابع وجود كائن Deferred رئيسي جديد يتتبَّع الحالة الإجماليَّة لجميع تلك الكائنات Deferred المعطاة. سيقبل التابع الكائن Deferred الرئيسي هذا حالما تصبح جميع الكائنات Deferred المُمرَّرة "مقبولة"، أو يرفضه إن كان أحد تلك الكائنات المُمرَّرة "مرفوض". ستنفَّذ دوال ردود النداء doneCallbacks التي أضيفت للكائن Deferred الرئيسي باستعمال deferred.done()
متى ما "قُبِلَ" هذا الكائن. توفِّر الوسائط المُمرَّرة إلى ردود النداء doneCallbacks إمكانيَّة استعمال القيم المقبولة لكل كائن من الكائنات Deferred المعطاة بحسب الترتيب الذي مُرَّرت فيه هذه الكائنات إلى jQuery.when()
. يشرح المثال التالي ما ذكر آنفًا:
var d1 = $.Deferred();
var d2 = $.Deferred();
$.when( d1, d2 ).done(function ( v1, v2 ) {
console.log( v1 ); // "سمكة"
console.log( v2 ); // "شجرة"
});
d1.resolve( "سمكة" );
d2.resolve( "شجرة" );
في حال "قٌبِلَ" الكائن Deferred دون أيَّة قيمة، فسيكون رد النداء doneCallback المقابل له غير معرَّف (undefined). وإن "قُبِلَ" الكائن Deferred مع قيمة وحيدة ،فسيأخذ وسيط دالة رد النداء doneCallback المقابلة هذه القيمة. أمَّا إن "قُبِلَ" الكائن Deferred مع قيم عديدة، فسيكون وسيط دالة رد النداء doneCallback المقابلة مصفوفةً تحوي جميع هذه القيم. توضح الشيفرة التالية هذا الكلام:
var d1 = $.Deferred();
var d2 = $.Deferred();
var d3 = $.Deferred();
$.when( d1, d2, d3 ).done(function ( v1, v2, v3 ) {
console.log( v1 ); // غير معرَّف v1
console.log( v2 ); // "هو "أبجد v2
console.log( v3 ); // [هو مصفوفة من القيم [ 1, 2, 3, 4, 5 v3
});
d1.resolve();
d2.resolve( "أبجد" );
d3.resolve( 1, 2, 3, 4, 5 );
في الحالة التي مُرِّر فيها عدَّة كائنات Deferred إلى jQuery.when()
وكان أحدها "مرفوضًا"، سيستدعي التابع دوال ردود النداء التي أضيفت للكائن Deferred الرئيسي لها باستعمال deferred.fail()
(تدعى failCallbacks). انتبه عند هذه الحالة إلى أنَّه ربما لا تزال حالة بعضٍ من تلك الكائنات المعطاة "غير معلَّق" (unresolved). ستأخذ الوسائط المُمرَّرة إلى ردود النداء failCallbacks القيم المقابلة لقيم الكائنات المرفوضة بحسب الترتيب الذي مُرَّرت فيه إلى jQuery.when()
(مثل الحالة السابقة تمامًا مع الكائنات المقبولة). إن أردت إنجاز عمليات إضافيَّة في هذه الحالة -مثل إلغاء طلبات Ajax غير المنتهية بعد-، فيمكنك إبقاء مرجعٍ إلى الكائنات jqXHR المضمَّنة في نطاق مغلق (closure) وفحصها أو إلغائها في رد النداء failCallback.
أمثلة
تنفيذ دالةٍ بعد نجاح إرسال طلبي Ajax (ارجع إلى توثيق الدالة jQuery.ajax()
لشرح أوسع حول حالات نجاح وفشل طلبات Ajax):
$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
// على التوالي page2 والطلب page1 القيمة التي يعيدها الطلب a2 والثاني a1 يأخذ الوسيط الأول
// [ data, statusText, jqXHR ] وبذلك يكون كل وسيط هو مصفوفة ذات البنية
var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
if ( /Whip It/.test( data ) ) {
alert( "لقد أنجزنا ما الذي استُدعينا من أجله :)" );
}
});
تنفيذ الدالة myFunc
عندما ينجح كلا طلبي Ajax أو تنفيذ الدالة myFailure
إن فشل أحد الطلبين:
$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) )
.then( myFunc, myFailure );