Promise.prototype.catch()

Метод catch() вертає проміс та має справу лише з відхиленнями. Він поводиться так само, як виклик Promise.prototype.then(undefined, onRejected) (насправді, obj.catch(onRejected) здійснює внутрішній виклик obj.then(undefined, onRejected)). Це означає, що ви маєте надати функцію onRejected, навіть якщо хочете отримати повернене значення undefined - наприклад, obj.catch(() => {}).

Синтаксис

p.catch(onRejected);

p.catch(function(reason) {
   // відхилення
});

Параметри

onRejected
Функція, що викликається, коли об'єкт Promise відхилено. Ця функція має один аргумент:
reason
Причина відхилення.
Проміс, повернений методом catch(), відхиляється, якщо onRejected викидає помилку або повертає проміс, що сам є відхиленим; інакше, він вирішується.

Значення, що повертається

Здійснює внутрішній виклик Promise.prototype.then на об'єкті, на якому був викликаний, передаючи параметри undefined та отриманий обробник onRejected. Повертає значення цього виклику, тобто, Promise.

Зауважте, що наведені нижче приклади викидають екземпляри Error. Це вважається гарною практикою у порівнянні з викиданням рядків: Інакше та частина, що здійснює перехоплення, була б змушена робити перевірки, щоб дізнатись, чи є аргумент рядком, чи помилкою, і ви могли б втратити цінну інформацію, таку як траси стеків.

Демонстрація внутрішнього виклику:

// заміщуємо початковий Promise.prototype.then/catch, щоб додати трохи логів
(function(Promise){
    var originalThen = Promise.prototype.then;
    var originalCatch = Promise.prototype.catch;
    
    Promise.prototype.then = function(){
        console.log('> > > > > > викликано .then на %o з аргументами: %o', this, arguments);
        return originalThen.apply(this, arguments);
    };
    Promise.prototype.catch = function(){
        console.error('> > > > > > викликано .catch на %o з аргументами: %o', this, arguments);
        return originalCatch.apply(this, arguments);
    };

})(this.Promise);



// викликаємо catch на вже вирішеному промісі
Promise.resolve().catch(function XXX(){});

// виводить:
// > > > > > > викликано .catch на Promise{} з аргументами: Arguments{1} [0: function XXX()]
// > > > > > > викликано .then на Promise{} з аргументами: Arguments{2} [0: undefined, 1: function XXX()]

Опис

Метод catch використовується для обробки помилок у композиції промісів. Оскільки він вертає проміс, його можна додавати в ланцюги так само, як метод then().

Приклади

Використання та ланцюгування метода catch

var p1 = new Promise(function(resolve, reject) {
  resolve('Успіх!');
});

p1.then(function(value) {
  console.log(value); // "Успіх!"
  throw new Error('о, ні!');
}).catch(function(e) {
  console.error(e.message); // "о, ні!"
}).then(function(){
  console.log('після catch ланцюг відновлено');
}, function () {
  console.log('Не запуститься через catch');
});

// Наступний код поводиться так само
p1.then(function(value) {
  console.log(value); // "Успіх!"
  return Promise.reject('о, ні!');
}).catch(function(e) {
  console.error(e); // "о, ні!"
}).then(function(){
  console.log('після catch ланцюг відновлено');
}, function () {
  console.log('Не запуститься через catch');
});

Підводні камені при викиданні помилок

// Викидання помилок викличе метод catch у більшості випадків
var p1 = new Promise(function(resolve, reject) {
  throw new Error('Ой-ой!');
});

p1.catch(function(e) {
  console.error(e); // "Ой-ой!"
});

// Помилки, викинуті всередині асинхронних функцій, поводитимуться, як неперехоплені
var p2 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    throw new Error('Неперехоплений виняток!');
  }, 1000);
});

p2.catch(function(e) {
  console.error(e); // Це ніколи не виконається
});

// Помилки, викинуті після виклику resolve, глушаться
var p3 = new Promise(function(resolve, reject) {
  resolve();
  throw new Error('Заглушений виняток!');
});

p3.catch(function(e) {
   console.error(e); // Це ніколи не виконається
});

Якщо він вирішений

//Створюємо проміс, що не викличе onReject
var p1 = Promise.resolve("виклик наступного");

var p2 = p1.catch(function (reason) {
    //Це ніколи не буде викликано
    console.error("перехоплено p1!");
    console.error(reason);
});

p2.then(function (value) {
    console.log("onFulfilled наступного проміса"); /* onFulfilled наступного проміса */
    console.log(value); /* виклик наступного */
}, function (reason) {
    console.log("onRejected наступного проміса");
    console.log(reason);
});

Специфікації

Специфікація
ECMAScript Latest Draft (ECMA-262)
The definition of 'Promise.prototype.catch' in that specification.

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
catch()Chrome Full support 32Edge Full support 12Firefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Firefox Android Full support 29Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support 2.0nodejs Full support 0.12

Legend

Full support  
Full support
No support  
No support

Див. також