الدالة Promise.prototype.catch()‎ في JavaScript

من موسوعة حسوب
< JavaScript‏ | Promise
مراجعة 12:58، 19 أبريل 2019 بواسطة جميل-بيلوني (نقاش | مساهمات) (إنشاء الصفحة. هذه الصفحة من مساهمات عبد اللطيف ايمش)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)
اذهب إلى التنقل اذهب إلى البحث

الدالة catch()‎ تعيد وعدًا Promise وتتعامل مع حالات رفض الوعود فقط. وهي تسلك نفس سلوك استدعاء الدالة Promise.prototype.then(undefined, onRejected)‎. وفي الواقع، استدعاء الدالة obj.catch(onRejected)‎ سيستدعي الدالة obj.then(undefined, onRejected)‎ داخليًا.

var promise1 = new Promise(function(resolve, reject) {
  throw 'Uh-oh!';
});

promise1.catch(function(error) {
  console.log(error);
});
// Uh-oh!

البنية العامة

p.catch(onRejected);

p.catch(function(reason) {
   // التعامل مع الرفض
});

المعاملات

onRejected

دالة تستدعى عند رفض الوعد Promise. هذه الدالة تملك معاملًا وحيدًا:

reason

سبب الرفض.

الوعد المُعاد من الدالة catch()‎ سيُرفَض إذا رمت الدالة onRejected أو أعادت وعدًا رُفِض بدوره؛ وإلا فسيكون الوعد مقبولًا.

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

هذه الدالة تستدعي الدالة ()Promise.prototype.then داخليًا على الكائن الذي اُستدعيت عليه، وتمرر الوسائط undefined والدالة onRejected التي مُرِّرت إليها، وتعيد قيمة ذاك الاستدعاء (والذي هو وعدٌ Promise).

تحذير: سنرمي سلاسل نصية في الأمثلة أدناه، وهذا أمرٌ غير منصوح به، حاول دومًا أن ترمي نسخةً من الكائن Error، وإلا فعلى الجزء الذي سيلتقط الاستثناء أن يتحقق من نوع المعامل (هل هو سلسلة نصية أم خطأ)، وقد تخسر معلومات قيّمة عن الخطأ.

مثال عن استدعاء داخلي:

// إعادة تعريف الدوال الأصلية لإضافة بعض الأسطر التي تُسجِّل الأحداث
(function(Promise){
    var originalThen = Promise.prototype.then;
    var originalCatch = Promise.prototype.catch;
    
    Promise.prototype.then = function(){
        console.log('> > > > > > called .then on %o with arguments: %o', this, arguments);
        return originalThen.apply(this, arguments);
    };
    Promise.prototype.catch = function(){
        console.log('> > > > > > called .catch on %o with arguments: %o', this, arguments);
        return originalCatch.apply(this, arguments);
    };

})(this.Promise);



// استخدام الدالة catch على وعد مقبول
Promise.resolve().catch(function XXX(){});

// الناتج:
// > > > > > > called .catch on Promise{} with arguments: Arguments{1} [0: function XXX()]
// > > > > > > called .then on Promise{} with arguments: Arguments{2} [0: undefined, 1: function XXX()]

الوصف

يمكن أن تكون الدالة ()catch مفيدةً لمعالجة الأخطاء في آلية الوعود التي تُطبِّقها.

أمثلة

استخدام سلسلة من الدوال مع الدالة ()catch

var p1 = new Promise(function(resolve, reject) {
  resolve('Success');
});

p1.then(function(value) {
  console.log(value); // "Success!"
  throw 'oh, no!';
}).catch(function(e) {
  console.log(e); // "oh, no!"
}).then(function(){
  console.log('after a catch the chain is restored');
}, function () {
  console.log('Not fired due to the catch');
});

// ما يلي سيسلك نفس سلوك الشيفرة السابقة
p1.then(function(value) {
  console.log(value); // "Success!"
  return Promise.reject('oh, no!');
}).catch(function(e) {
  console.log(e); // "oh, no!"
}).then(function(){
  console.log('after a catch the chain is restored');
}, function () {
  console.log('Not fired due to the catch');
});

رمي الأخطاء

رمي خطأ في وعد سيؤدي إلى استدعاء الدالة ()catch في أغلبية الأوقات:

var p1 = new Promise(function(resolve, reject) {
  throw 'Uh-oh!';
});

p1.catch(function(e) {
  console.log(e); // "Uh-oh!"
});

الأخطاء المرمية داخل الدوال غير المتزامنة ستُعامل معاملة الاستثناءات غير المعالجة:

var p2 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    throw 'Uncaught Exception!';
  }, 1000);
});

p2.catch(function(e) {
  console.log(e); // لن يصل الاستدعاء إلى هنا
});

لن يُعتد بالأخطاء المرمية بعد استدعاء الدالة resolve()‎:

var p3 = new Promise(function(resolve, reject) {
  resolve();
  throw 'Silenced Exception!';
});

p3.catch(function(e) {
   console.log(e); // لن يصل الاستدعاء إلى هنا
});

في حالة قبول الوعد

إنشاء وعد لن يستدعي onReject:

var p1 = Promise.resolve("calling next");

var p2 = p1.catch(function (reason) {
    // لن يجري استدعاء ما يلي مطلقًا
    console.log("catch p1!");
    console.log(reason);
});

p2.then(function (value) {
    console.log("next promise's onFulfilled"); /* next promise's onFulfilled */
    console.log(value); /* calling next */
}, function (reason) {
    console.log("next promise's onRejected");
    console.log(reason);
});

انظر أيضًا

  • الدالة then()‎: تعيد وعدًا Promise، وتأخذ وسيطين على الأكثر، وهما دالتا رد النداء (callback) لنجاح أو فشل الوعد.
  • الدالة resolve()‎: تعيد كائن Promise مقبول مع القيمة (value) المحددة.

المصادر