2015-12-11 2 views
6

Попробуйте этот кусок кода на консоли вкладке Chrome или FirefoxКак работает «улов» в собственной цепочке обещаний?

var p = new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     reject(10); 
    }, 1000) 
}) 

p.then(function(res) { console.log(1, 'succ', res) }) 
.catch(function(res) { console.log(1, 'err', res) }) 
.then(function(res) { console.log(2, 'succ', res) }) 
.catch(function(res) { console.log(2, 'err', res) }) 

Результат будет

1 "err" 10 
2 "res" undefined 

я пробовал много других примеров, но мне кажется, что первый then() возвращает обещание, что всегда решает и никогда не отвергает. Я пробовал это на Chrome 46.0.2490.86 и Firefox 42.0. Почему это происходит? Я думал, что then() и catch() могут быть цепями несколько раз?

+0

Возможный дубликат [Цепные обещания, не проходящие при отказе] (http://stackoverflow.com/q/16371129/1048572) – Bergi

ответ

7

Так же, как в синхронном коде:

try { 
    throw new Error(); 
} catch(e) { 
    console.log("Caught"); 
} 
console.log("This still runs"); 

код, который работает после исключение было обработано будет работать - это потому, что исключения являются механизм восстановления ошибок. Добавив этот catch, вы указали, что ошибка была обработана. В синхронном случае мы обрабатываем это путем Повторное выбрасывание:

try { 
    throw new Error(); 
} catch(e) { 
    console.log("Caught"); 
    throw e; 
} 
console.log("This will not run, still in error"); 

Обещания работают аналогично:

Promise.reject(Error()).catch(e => { 
     console.log("This runs"); 
     throw e; 
}).catch(e => { 
     console.log("This runs too"); 
     throw e; 
}); 

Как наконечник - никогда не отклонять с не- Error с, как вы потеряете много полезных вещей, как значимый стек следы.

2

Почему это происходит? Я думал, что then() и catch() могут быть целыми несколько раз?

@Benjamin прав, +1, но поставить его по-другому, эти правила: методы

  • Если добавить then несколько раз, вы что цепные должны быть названы в последовательности , пока не будет выбрано исключение. Исключения в цепи then должны обрабатываться catch, объявленными после then. Если после then нет catch, эта ошибка будет запущена: Uncaught (in promise) Error(…).
  • Если вы добавили catch несколько раз, вы цепляете методы, которые следует вызывать, когда что-то пойдет не так (в функциях then). Однако второй catch в цепочке будет вызываться только в том случае, если первый повторит исключение и так далее.
  • При запуске catch цепь возобновляется на следующем then, объявленном после catch.