البحث في الموقع
المحتوى عن 'تعلّم'.
-
في الماضي القريب، كانت مهنة الهندسة واضحةً نسبياً. درست لغة معينةً أو أكثر، حصلت على عمل ونجحت. لم يعد هذا الأمر صحيحاً اليوم، فمعدل التغير المتزايد في التقنية يعني أنه بات من الصعب إتقان أي شيء قبل أن يعدّ قديماً ويُستبدل بمنافس أجدد وأبهى. لا تُعنى المسيرة الهندسية الناجحة اليوم بالتعمق في مهارة معينة، بل بالانفتاح لتعلم تقنيات جديدة بسرعة أكبر، وفهم كيف قد يغير ذلك ما يعنيه أن تكون خبيراً. عدد لا متناهٍ من المبتدئين في كتابه الأخير “المحتوم The Inevitable”، يدّعي المحرر التنفيذي المؤسس لـ وييرد Wired كيفن كيلي Kevin Kelly أن هذه الوتيرة السريعة والمتزايدة للتغيير تخلق ما يصفه بـ “العدد اللامتناهي من المبتدئين”. التقنيات التي ستسيطر على مدى 30 سنة المقبلة لم تُخترع بعد وبالتالي سنكون جميعنا “مبتدئين” بالنسبة لها، بغض النظر عن العمر أو الخبرة. فكّر بالأمر في سياق مسيرتك المهنية. في العادة، جرى تدريب المهندسين على وضع توزّع للمهارات الهندسية على شكل حرف T، فالشريط الأفقي يشير إلى اتساع مهاراتك في نواحٍ مختلفة، والشريط العمودي يشير إلى تعمقك في مجالٍ معين. لكنّ ظهور العدد الكبير من المبتدئين يعني أن الشريط الأفقي أصبح أعرض، والأكثر أهمية من ذلك أن الشريط العمودي أصبح أقصر يعني الشكل الجديد للحرف T زمناً وخبرة أقل من أجل تقنية معينة. أصبح الشريط العمودي أقصر لأن التقنية تتغير بسرعة أكبر. لا يزال عليك التعمّق في مجال معين، لكنه من غير المحتمل أن تضطر إلى العمل مستخدماً تقنية واحدة فقط خلال كامل مسيرتك المهنية. يرتبط طول الشريط العمودي بالزمن والخبرة. إن كانت التقنية والمنتجات تتغير بسرعة كبيرة، فسيكون لديك وقت أقل للتعمق في مجال واحد قبل أن يظهر منافس آخر على الساحة. كما أن معدل التغيير سيؤثر أيضاً على اتساع الشخصية التقليدية التي تتبع التوزع من الشكل T. وبما أنه سيكون هناك المزيد من التقنيات الحديثة، يصبح من المهم توسيع قاعدة المهارات والمعارف للمنتجات والخدمات المختلفة. لن تعرف من أين سيظهر المنتج أو الخدمة الجديدة التالية لذا عليك أن تُحصّن نفسك. أعطني T لقد واجهت هذا مؤخراً عندما كنت أعمل على خدمة التخزين S3 من خدمات ويب أمازون (AWS). كنت أحاول الاستعلام عن البيانات المخزنة في S3، وهو ما كان يعني في السابق استخراج وتحويل البيانات لأتمكّن من استجوابها. بجميع الأحوال، أطلقت AWS في السنة الماضية خدمة جديدة تدعى Athena ، مما يعني أنه بإمكاني الاستعلام عن البيانات في S3 لحظياً. بينما كنت أعمل مع Athena، ذكر أحدهم أن AWS أطلقت للتو خدمة أجدد تدعى Spectrum تسمح لك بإجراء استعلامات Redshift SQL مباشرة في S3. بإمكاني الآن استخدام Spectrum عوضاً عن Athena بالرغم من أنني اكتشفت Athena منذ شهر أو شهرين فقط! وإذا ما أخذنا بالحسبان وجود قلة من الأشخاص فقط يستخدمون Athena في الشركة التي أعمل بها، فقد كنت تقنياً واحداً من “الخبراء” في هذا المجال. هناك خدمات “جديدة” لكنها مبنية على مهارات أخرى، مثل استخدام استعلامات SQL للاستعلام عن البيانات أو معرفة المنتجات مثل S3 و Redshift. في السابق، كنت تركز على تقنية لقاعدة البيانات مثل MySQL أو Postgres وتقوم بزيادة التعمق العامودي لل T الخاص بك. في الوقت الراهن، ومع التغير السريع للمنتجات والخدمات، فإن كلمة خبير تعني التبديل بين المهارات بسرعة أكبر والتكيف مع التغيرات الجديدة والتخلي عن بعض المهارات. يغير هذا الأمر الكثير من الأسس التي ترتكز عليها مهنة الهندسية التقليدية. اذهب إلى الجامعة، تعلم إحدى المهارات، انضم إلى شركة تعمل في هذا المجال، طور نفسك، احصل على ترقية، أصبح خبيراً وطور مواردك البشرية. هل من المنطقي أن تذهب إلى الجامعة لمدة أربع سنوات لتتعلّم تقنية قد تختفي عندما تتخرج؟ فكر في تقنيات مثل Hadoop، التي ظهرت إلى العلن عام 2007 لكنها اليوم تعدّ “قديمة” مقارنة مع التقنيات الأحدث في علم البيانات. إن تعلّم أشياء جديدة بسرعة دون التعمق فيها كما اعتدنا أن نفعل، أمر يسهل قوله أكثر من فعله. نقدّر نحن البشر مهاراتنا ومعارفنا ونحرص على ألا ننساها. عندما بدأت العمل في مجال عمليّات التطوير DevOps، كنت أستخدم Bash لغة برمجة أساسية. عندما تعتاد على البرمجة باستخدام Bash، يمكنك أن تقوم بأشياء فظيعة بواسطتها. تابعت تعلّم لغات برمجة أخرى مثل تعلم بايثون لكنني بقيت استخدم Bash في الكثير من الحالات لأنني كنت على دراية بها. الآن، أنظر إلى الوراء وأدرك أنني كنت بطيئاً جداً في التخلي عن Bash، وأن تعلّم شيء كبايثون بسرعة أكبر كان ليساعد مسيرتي المهنية أكثر. يصعب التخلي عن شيء تشعر أنك جيد أو ملمّ به. قم بجولة في عالم الهندسة إن التحدي الحقيقي الذي يواجه الهندسة ليس استيلاء الأتمتة والذكاء الاصطناعي على وظائف البشر. الخطر الحقيقي هو الإحجام عن فهم أن مفهومنا للخبير يتغير. أن تكون خبيراً في شيء ما اليوم يعني بناء قاعدة أوسع من المهارات حتى تتمكن من التعمق عند الحاجة في تلك التقنية أو في ذلك المنتج. إن كانت الأمور تتغير على نحو أسرع من أي وقت مضى، فكذلك يجب على مجال خبرتك أيضاً أن يتغير. على سبيل المثال، نحن نكتب بالفعل خوارزميات لتعليم الآلة كي تقوم بكتابة التعليمات البرمجية بنفسها. لذا علينا أن نكون جاهزين للانتقال بسرعة من كتابة التعليمات البرمجية فقط إلى تصميم الخوارزميات. يعني ذلك بالطبع تعلّم بعض المهارات الحسابية لتطوير هذه الخوارزميات الجديدة. ولكن في تلك الحالة سيصبح المهندسون أفضل لا أسوأ بفضل التلقيح بين مجموعات المهارات. القليل من تعليم الآلة والقليل من تصميم الخوارزميات والقليل من كتابة التعليمات البرمجية وبعض المعرفة في مجال العمل. يمكّنك توزع T الأعرض من المهارات الأساسية أن تتعمق عمودياً بسهولة عند وصول ذاك المنتج الجديد إلى الساحة. نحاول في Intercom إعداد الناس لهذا المستقبل وذلك من خلال ضمان قيام المهندسين “بجولات” على مختلف الفرق. يقضي المهندسون بضعة أسابيع في العمل على فريق مختلف أو على جزء مختلف من المنتج. فقد يعمل الشخص الذي اعتاد العمل على القضايا التشغيلية الخلفية Backend في فريق يعمل على تطوير الواجهة الأمامية Frontend. وبطريقة مماثلة، قد يعمل شخص ما مع فريق التحليل لمدة من الزمن ليتعلم عن عرض البيانات أو تعليم الآلة. الهدف هنا هو توسيع T بحيث يتمكن الناس من التكيف بسرعة أكبر مع التقنيات الجديدة التي تُنشَأ يومياً. بهذه الطريقة يفهمون التقنيات الجديدة في مجالات أخرى ويمكنهم إما أن يعودوا بها لاستخدامها في دورهم الحالي أو أن يتطلعوا إلى قضاء المزيد من الوقت في فريق آخر. هناك هدف متمم للعمل مع أناس مختلفين في فرق مختلفة. وفي كلتا الحالتين، فإنه يمكّن الناس من أن يصبحوا أكثر قدرة على التكيف مع مسيراتهم الهندسية. تعلم كيف تنسى إن التنبؤ بالمستقبل أمر صعب. يمكننا رصد الاتجاهات الكبرى في التقنية، لكن يستحيل التنبؤ بالشكل المعين الذي ستتخذه. وعلى نحو مشابه، لا يمكننا أن نفهم تماماً التقنيات التي ستتطلّبها مسيرتنا الهندسية المستقبلية. ما نعرفه هو أن هذا التغير السريع أمر حتمي لا مفر منه. بغض النظر عن المهارات التي تملكها أو لغات البرمجة التي تبرع فيها، ستصبح بعض الجوانب منسية في المستقبل القريب. لذ اسأل نفسك: ما الذي يمكن أن أنساه؟ لن يكون أمراً سهلاً. ستكون مبتدئاً في مهارة جديدة عوضاً عن عمود المعرفة الذي كنت عليه سابقاً. لكنك ستكون جاهزاً على نحو أفضل بكثير للتعامل مع التقنيات الجديدة عند ظهورها. ترجمة - بتصرّف - للمقال Learn, unlearn and relearn: the changing face of your engineering career لصاحبه Cathal Horan. حقوق الصورة البارزة محفوظة لـ Freepik
-
AJAXAJAX هي اختصار للعبارة "asynchronous JavaScript and XML"، وهي وسيلة لجلب البيانات من الخادوم دون الحاجة لإعادة تحميل الصّفحة، وهي تقوم على استخدام كائن مُتاح في المتصفّح اسمه XMLHttpRequest (أو XHR اختصارًا) لإرسال الطّلب إلى الخادوم ثمّ التّعامل مع البيانات الّتي يُجيب بها الخادوم. تُوفّر jQuery الوظيفة $.ajax (ووظائف أخرى مرافقة مُختصرة) لتسهيل العمل مع طلبات XHR في جميع المتصفّحات. $.ajaxبإمكاننا استخدام الوظيفة $.ajax() المُرفقة مع jQuery بعدّة أساليب: إحداها أن نُمرّر إليها كائنًا يحوي الإعدادات فقط، أو أن نُمرّر الرّابط مع أو بدون كائن الإعدادات. لنُلقِ نظرة على الأسلوب الأول: // أنشئ دالّة الاستدعاء الرّاجع الّتي ستُنفّذ عندما ينجح طلب AJAX var updatePage = function( resp ) { $( '#target').html( resp.people[0].name ); }; // وعندما يفشل var printError = function( req, status, err ) { console.log( 'something went wrong', status, err ); }; // أنشئ كائن الإعدادات الذي يصف الطّلب var ajaxOptions = { url: '/data/people.json', dataType: 'json', success: updatePage, error: printError }; // أرسل الطّلب $.ajax(ajaxOptions);بإمكانك طبعًا أن تُمرّر كائنًا حرفيًّا مباشرةً إلى الوظيفة$.ajax() وأن تستخدم دالّة مجهولة محلّ success وerror، هذا الأسلوب كتابته أسهل، وصيانته في المستقبل أسهل: $.ajax({ url: '/data/people.json', dataType: 'json', success: function( resp ) { $( '#target').html( resp.people[0].name ); }, error: function( req, status, err ) { console.log( 'something went wrong', status, err ); } });كما قلنا، بإمكانك استخدام الوظيفة$.ajax() بأسلوب ثانٍ، وذلك بتمرير الرّابط أوّلًا ثمّ كائن الإعدادات ثانيًا (ليس إلزاميًّا). يُفيدك هذا في حال رغبت في استخدام الإعدادات المبدئيّة للوظيفة أو في حال رغبت في استخدام كائن الإعدادات نفسه لأكثر من رابط: $.ajax( '/data/people.json', { type: 'GET', dataType: 'json', success: function( resp ) { console.log( resp.people ); }, error: function( req, status, err ) { console.log( 'something went wrong', status, err ); } });في المثال السّابق، لا تشترط الوظيفة سوى الرّابط، ولكنّ إضافة كائن الإعدادات تسمح لنا بإخبار jQuery بنوع البيانات الّتي نُرسلها، وأي فعل HTTP نستخدمه (POST، GET، إلخ...)، وما نوع البيانات الّتي نتوقّع استقبالها من الخادوم، وما الّذي يجب فعله إن نجح الطّلب أو فشل... اطّلع على وثائق الوظيفة$.ajax() لقراءة كامل الخيارات الّتي يمكن إضافتها إلى كائن الإعدادات. A في AJAX تعني "لامتزامن"تجري طلبات AJAX بصورة لا متزامنة، وهذا يعني أنّ الوظيفة$.ajax تنتهي قبل انتهاء الطّلب، وقبل أن تُستدعى دّالة success، أيّ أنّ جملة return تُنفّذ قبل أن يصل جواب الطّلب. فالدّالة getSomeData في المثال التّالي ستُعيد قيمة data قبل أن تُعرّف، مما يؤدّي إلى وقوع خطأ: تحذير: نصّ برمجيّ غير سليم var getSomeData = function() { var data; $.ajax({ url: '/data/people.json', dataType: 'json', success: function(resp) { data = resp.people; } }); return data; } $( '#target' ).html( getSomeData().people[0].name );X في AJAX تعني JSON!وضع المصطلح AJAX عام 2005 ليصف طريقة لجلب البيانات من الخادوم دون الحاجة لإعادة تحميل كامل الصّفحة. في ذلك الوقت، كانت الصّيغة الأكثر شيوعًا للبيانات الّتي تُرسلها الخوادم هي XML، أمّا اليوم، فإنّ JSON هي الصّيغة الّتي تعتمدها أكثر التّطبيقات الحديثة. صيغة JSON في أساسها هي سلسلة نصّيّة (string) تُمثّل البيانات، وتبدو مُشابهة كثيرًا لكائن JavaScript عاديّ، ولكنّها لا تستطيع تمثيل كلّ أنواع البيانات الّتي يستطيع كائن JavaScript تمثيلها. فمثلًا: لا يمكن لـJSON تمثيل كائنات التّاريخ (Date) ولا الدّوال (functions). فيما يلي مثال عن نصّ JSON، لاحظ كيف تُحاط كلّ أسماء الخصائص بعلامتي اقتباس مُضاعفتين: { "people" : [ { "name" : "Ben", "url" : "http://benalman.com/", "bio" : "I create groovy websites, useful jQuery plugins, and play a mean funk bass. I'm also Director of Pluginization at @bocoup." }, { "name" : "Rebecca", "url" : "http://rmurphey.com", "bio" : "Senior JS dev at Bocoup" }, { "name" : "Jory", "url" : "http://joryburson.com", "bio" : "super-enthusiastic about open web education @bocoup. lover of media, art, and fake mustaches." } ] }تذكّر أنّ JSON هو تمثيل نصّيّ لكائن، ما يعني أنّه يجب تفسير السّلسلة النّصيّة لتحويلها إلى كائن JavaScript عاديّ قبل التّعامل معها. عندما تعمل مع جواب ورد من الخادوم بصيغة JSON، فإنّ jQuery تتولّى هذه المهمّة عنك. ولكن من المهمّ التمييز بين الكائنات الفعليّة، وطريقة تمثيلها في JSON. ملاحظة: إن أردت إنشاء سلسلة JSON نصّيّة من كائن JavaScript أو تفسير سلسلة JSON نصّيّة لتحويلها إلى كائن JavaScript دون الاستعانة بـjQuery، فإنّ المُتصفّحات الحديثة تُقدّم الوظيفتين JSON.stringify() وJSON.parse()، ويمكن إضافة هذه الخصائص إلى المُتصفّحات القديمة باستخدام المكتبة json2.js. توفّر jQuery أيضًا وظيفة jQuery.parseJSON()، الّتي توافق الوظيفة JSON.parse() في المتصفّحات، إلّا أنّها لا توفّر وظيفة تُقابل JSON.stringify(). وظائف مُختصرةإن كان كلّ ما نريده إرسال طلب بسيط، دون الاهتمام بالتّعامل مع الأخطاء الّتي قد تقع، فإنّ jQuery تُوفّر وظائف مُختصرة تسمح لنا بفعل ذلك. تستقبل كل وظيفة مُختصرة رابطًا وكائن إعدادات غير إلزاميّ، ودالّة تُستدعى عند نجاح الطّلب فقط: $.get( '/data/people.html', function( html ){ $( '#target' ).html( html ); }); $.post( '/data/save', { name: 'Rebecca' }, function( resp ) { console.log( resp ); });إرسال البيانات والعمل مع النّماذجبإمكاننا إرسال بيانات مع طلبنا بتعيين قيمة للخاصة data في كائن الإعدادات، أو تمرير كائن كمُعامل ثانٍ للوظائف المُختصرة. ستُضاف هذه البيانات إلى الرّابط في طلبات GET بصورة "جملة استعلام" (query string)، أمّا في طلبات POST فإنّها ستُرسل كبيانات نموذج. توفّر jQuery وظيفة مُفيدة .serialize() الّتي تستقبل مُدخلات نموذج وتُحوّلها إلى صيغة "جملة استعلام" (مثل field1name=field1value&field2name=field2value...): $( 'form' ).submit(function( event ) { event.preventDefault(); var form = $( this ); $.ajax({ type: 'POST', url: '/data/save', data: form.serialize(), dataType: 'json', success: function( resp ) { console.log( resp ); } }); });jqXHRتُعيد$.ajax() والوظائف المُختصرة المرافقة لها، كائن jqXHR (اختصارًا لـjQuery XML HTTP Request) والّذي يتضمّن وظائف مُفيدةً كثيرة. بإمكاننا إرسال طلب باستخدام $.ajax() ثمّ حفظ كائن jqXHR في مُتغيّر: var req = $.ajax({ url: '/data/people.json', dataType: 'json' });بإمكاننا استخدام هذا العنصر لربط الاستدعاءات الرّاجعة بالطّلب، حتّى بعد أن يكتمل الطّلب. بإمكاننا مثلًا استخدام الوظيفة .then() (ثُمَّ) لإرفاق استدعاءي نجاح الطّلب وفشله، إذ تقبل .then() دالّة أو اثنتين، تستدعى الأولى عند نجاح الطّلب، والثّانية إن فشل: var success = function( resp ) { $( '#target' ).append( '<p>people: ' + resp.people.length + '</p>' ); console.log( resp.people ); }; var err = function( req, status, err ) { $( '#target' ).append( '<p>something went wrong</p>' ); }; req.then( success, err ); req.then(function() { $( '#target' ).append( '<p>it worked</p>' ); });بإمكاننا استدعاء .then() على كائن الطّلب قدر ما نشاء، وستُنفّذ الاستدعاءات الرّاجعة بالتّرتيب ذاته الّتي أرفقت وفقه. إن لم نُرد إرفاق استدعاءي النّجاح والفشل معًا، فبإمكاننا استخدام الوظيفتين .done() و.fail() على كائن الطّلب: req.done( success ); req.fail( err );لو أردنا إرفاق استدعاء راجعٍ يُنفَّذ دومًا، بغض النّظر عن نجاح الطّلب أو فشله، فيمكننا استخدام الوظيفة .always() على كائن الطّلب: req.always(function() { $( '#target' ) .append( '<p>one way or another, it is done now</p>' ); });JSONPيستغرب كثيرٌ من المبتدئين في JavaScript فشل طلبات XHR الّتي يرسلونها إلى نطاق آخر على الإنترنت، فمثلاً: يحاول بعض المُطوّرين جلب بيانات من واجهة برمجيّة من طرف ثالث (third-party API)، ليفاجؤوا بفشل الطّلب باستمرار. السّبب وراء ذلك أنّ المُتصفّحات لا تسمح بإرسال طلبات XHR إلى نطاقات إنترنت أخرى لأسباب أمنيّة، ولكنّ بعض الواجهات البرمجيّة تُعيد البيانات بصيغة JSONP (اختصارًا لـJSON with Padding)، الّتي تسمح للمُطوّرين بجلب البيانات متجاوزين حظر المُتصفّح. الحقيقة أن JSONP ليس طلب AJAX فعليًّا، فهو لا يستخدم طلب XHR الّذي يوفّره المُتصفّح، بل يعمل بإدراج وسم <script> في صفحة الويب، الّذي يحوي بدوره البيانات المطلوبة، مُحاطة بدالّة تُعيد هذه البيانات عند استدعائها. ليس هذه التّفاصيل مهمّة الآن، لأنّ jQuery تسمح لك بطلب JSONP كما لو كان XHR باستخدام الوظيفة $.ajax() بتعيين نوع البيانات dataType إلى 'jsonp' في كائن الإعدادات. $.ajax({ url: '/data/search.jsonp', data: { q: 'a' }, dataType: 'jsonp', success: function( resp ) { $( '#target' ).html( 'Results: ' + resp.results.length ); } });ملاحظة: عادةً ما توفّر الواجهات البرمجيّة خيارًا لتعيين اسم الدّالّة الّتي تُحيط بالبيانات والّتي ستُستدعى في عنوان الرّابط. عادةً ما يكون هذا اسم مُعامل الرّابط callback، وهذا ما تتوقّعه jQuery مبدئيًّا، إلّا أن بإمكانك تغييره بتعيين قيمة للخاصة jsonp في كائن الإعدادات الّذي تُمرّره لـ $.ajax(). بإمكانك أيضًا استخدام الوظيفة المُختصرة $.getJSON() لإرسال طلب JSONP، حيث تستطيع jQuery تمييزه من خلال وجود callback=? أو ما يشبهها في الرّابط: $.getJSON( '/data/search.jsonp?q=a&callback=?', function( resp ) { $( '#target' ).html( 'Results: ' + resp.results.length ); } );مشاركة الموارد عبر الأصول (cross-origin resource sharing أو CORS اختصارًا) هي خيارٌ آخر للسّماح بالطّلبات العابرة للأصول. ولكنّها غير مدعومة في المتصفّحات القديمة، كما أنّها تحتاج تهيئة خاصّة على الخادوم وتعديل ترويسات الطّلبات في XHR لتعمل. الكائنات المُؤجّلة (Deferreds)ليست كائنات jqXHR الّتي تعرّفنا عليها إلا "نكهة" خاصّة ممّا يُعرف "بالكائنات المؤجّلة". تسمح jQuery لك بإنشاء كائنات مؤجّلة بنفسك، والّتي يمكن الاستفادة منها في تسهيل التّعامل مع الأوامر اللامتزامنة، فهي توفّر طريقة للاستجابة لعمليّة تجري بصورة غير متزامنة بعد نجاحها أو فشلها، وتجنّبك الحاجة لكتابة استدعاءات راجعة مُتداخلة فيما بينها. $.Deferredبإمكانك إنشاء كائنٍ مؤجّل باستخدام $.Deferred(). في المثال التّالي نُنفّذ دالة داخل setTimeout، ثمّ "نفي" (resolve) بوعدنا بإعادة القيمة الّتي تُرجعها الدّالة هذه. نُعيد الوعد (promise)، وهو كائن يمكن ربط الاستدعاءات الرّاجعة به، ولكنّه لا يؤثّر في نتيجة الكائن المؤجّل بحدّ ذاته. بإمكاننا "الإخلاف" (reject) بالوعد إذا وقع خطأ ما أثناء عمل الدّالّة: function doSomethingLater( fn, time ) { var dfd = $.Deferred(); setTimeout(function() { dfd.resolve( fn() ); }, time || 0); return dfd.promise(); } var promise = doSomethingLater(function() { console.log( 'This function will be called in 100ms' ); }, 100);.then() و.done() و.fail() و.always()يمكننا ربط دوالّ تتولّى حالات الخطأ والنّجاح بالوعود، تمامًا كما في كائنات jqXHR: function doSomethingLater( fn, time ) { var dfd = $.Deferred(); setTimeout(function() { dfd.resolve( fn() ); }, time || 0); return dfd.promise(); } var success = function( resp ) { $( '#target' ).html( 'it worked' ); }; var err = function( req, status, err ) { $( '#target' ).html( 'it failed' ); }; var dfd = doSomethingLater(function() { /* ... */ }, 100); dfd.then( success, err );.pipe()بإمكاننا استخدام الوظيفة .pipe() للوعود للاستجابة إلى القيمة الّتي تُوفى وذلك بتعديلها ثمّ إعادة كائن مؤجّل جديد. تعمل الوظيفة .then() بدءًا من الإصدارة 1.8 من jQuery كما تعمل الوظيفة .pipe(). function doSomethingLater( fn, time ) { var dfd = $.Deferred(); setTimeout(function() { dfd.resolve( fn() ); }, time || 0); return dfd.promise(); } var dfd = doSomethingLater(function() { return 1; }, 100); dfd .pipe(function(resp) { return resp + ' ' + resp; }) .done(function(upperCaseResp) { $( '#target' ).html( upperCaseResp ); });التّعامل مع العمليّات الّتي قد تكون لامتزامنةأحيانًا تكون لدينا وظيفة قد تعمل بصورة متزامنة أو لا متزامنة وفق ظروف مُعيّنة، فمثلًا: دالّة تقوم بعمليّة لا متزامنة أوّل مرّة تُستدعى فيها، ثمّ تُخزّن القيمة الّتي أنتجتها العمليّة لتُعيدها مباشرةً عند استدعاءها مُستقبلًا. في هذه الحالة يمكننا الاستفادة من $.when() للاستجابة لكلا الحالتين: function maybeAsync( num ) { var dfd = $.Deferred(); // أعِد وعدًا مؤجّلًا عندما num === 1 if ( num === 1 ) { setTimeout(function() { dfd.resolve( num ); }, 100); return dfd.promise(); } // أنهِ مباشرة فيما سوى ذلك، مُعيدًا num return num; } // هذا سيُجرى بصورة غير متزامنة ويعِد بإعادة 1 $.when( maybeAsync( 1 ) ).then(function( resp ) { $( '#target' ).append( '<p>' + resp + '</p>' ); }); // هذا سُيعيد 0 مُباشرةً $.when( maybeAsync( 0 ) ).then(function( resp ) { $( '#target' ).append( '<p>' + resp + '</p>' ); });بإمكانك أيضًا تمرير أكثر من معامل إلى $.when()، الأمر الّذي يسمح لك بدمج عمليّات متزامنة ولا متزامنة معًا ثمّ الحصول على نتائج تنفيذها كلّها كُمعاملات للاستدعاء الرّاجع: function maybeAsync( num ) { var dfd = $.Deferred(); // أعد وعدًا مؤجّلًا عندما num === 1 if ( num === 1 ) { setTimeout(function() { dfd.resolve( num ); }, 100); return dfd.promise(); } // أنهِ مباشرةً فيما سوى ذلك، مُعيدًا num return num; } $.when( maybeAsync( 0 ), maybeAsync( 1 ) ) .then(function( resp1, resp2 ) { var target = $( '#target' ); target.append( '<p>' + resp1 + '</p>' ); target.append( '<p>' + resp2 + '</p>' ); });عندما يكون إحدى مُعاملات $.when() كائن jqXHR، فإنّنا نحصل على مصفوفة من المُعاملات تُمرّر إلى استدعائنا الرّاجع: function maybeAsync( num ) { var dfd = $.Deferred(); // أعد وعدًا مؤجّلًا عندما num === 1 if ( num === 1 ) { setTimeout(function() { dfd.resolve( num ); }, 100); return dfd.promise(); } // أنهِ مباشرةً فيما سوى ذلك، مُعيدًا num return num; } $.when( maybeAsync( 0 ), $.get( '/data/people.json' ) ) .then(function( resp1, resp2 ) { console.log( "Both operations are done", resp1, resp2 ); });مصادر إضافيةتوثيق AJAXكائن jqXHRالكائنات المؤجّلة في jQueryترجمة (بشيء من التصرف) للجزء السادس من سلسلة jQuery Fundamentals لمؤلّفتها Rebecca Murphey.
-
- javascript
- http
-
(و 6 أكثر)
موسوم في: