Мне сложно понять разницу между помещением .catch
BEFORE и AFTER во вложенное обещание.
Альтернатива 1:
test1Async(10).then((res) => {
return test2Async(22)
.then((res) => {
return test3Async(100);
}).catch((err) => {
throw "ERROR AFTER THEN";
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
Альтернатива 2:
test1Async(10).then((res) => {
return test2Async(22)
.catch((err) => {
throw "ERROR BEFORE THEN";
})
.then((res) => {
return test3Async(100);
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
Поведение каждой функции следующее: test1 не работает, если число равно <0
test2, если число равно, > 10
и test3 не работает, если число нет 100
. В этом случае test2 только терпит неудачу.
Я попытался запустить и сделать test2Async неуспешным, и BEFORE, и AFTER затем ведут себя одинаково, и это не выполняет test3Async. Может кто-нибудь объяснить мне главное отличие размещения улова в разных местах?
В каждой функции я console.log('Running test X')
проверяю, выполняется ли она.
Этот вопрос возникает из-за предыдущей темы, которую я опубликовал. Как превратить вложенный обратный вызов в обещание? . Я полагаю, что это другая проблема и стоит опубликовать другую тему.
источник
Ответы:
Итак, в основном вы спрашиваете, в чем разница между этими двумя (где
p
обещание, созданное из некоторого предыдущего кода):и
Существуют различия, когда p разрешает или отклоняет, но значение этих различий зависит от того, что делает код внутри обработчиков
.then()
or.catch()
.Что происходит при
p
разрешении:В первой схеме при
p
разрешении.then()
вызывается обработчик. Если этот.then()
обработчик возвращает значение или другое обещание, которое в конечном итоге выполняется,.catch()
обработчик пропускается. Но если.then()
обработчик либо бросает, либо возвращает обещание, которое в конечном итоге отклоняет, тогда.catch()
обработчик выполнит как отклонение в исходном обещанииp
, так и ошибку, которая возникает в.then()
обработчике.Во второй схеме при
p
разрешении.then()
вызывается обработчик. Если этот.then()
обработчик либо выбрасывает, либо возвращает обещание, которое в конечном итоге отклоняет, то.catch()
обработчик не может его поймать, потому что он находится перед ним в цепочке.Итак, это отличие №1. Если
.catch()
обработчик AFTER, он также может перехватывать ошибки внутри.then()
обработчика.Что происходит при
p
браке:Теперь, в первой схеме, если обещание
p
отклоняется, то.then()
обработчик пропускается, и.catch()
обработчик будет вызван, как и следовало ожидать. То, что вы делаете в.catch()
обработчике, определяет, что будет возвращено в качестве окончательного результата. Если вы просто возвращаете значение из.catch()
обработчика или возвращаете обещание, которое в конечном итоге разрешается, тогда цепочка обещаний переходит в разрешенное состояние, потому что вы «обработали» ошибку и вернулись нормально. Если вы выбрасываете или возвращаете отклоненное обещание в.catch()
обработчике, то возвращенное обещание остается отклоненным.Во второй схеме, если промис
p
отклоняется,.catch()
вызывается обработчик. Если вы возвращаете нормальное значение или обещание, которое в конечном итоге разрешается от.catch()
обработчика (таким образом «обрабатывая» ошибку), то цепочка обещаний переключается в разрешенное состояние, и будет вызван.then()
обработчик после.catch()
.Итак, это различие №2. Если
.catch()
обработчик - BEFORE, он может обработать ошибку и разрешить.then()
вызов обработчику.Когда использовать:
Используйте первую схему, если вам нужен только один
.catch()
обработчик, который может перехватывать ошибки либо в исходном обещании,p
либо в.then()
обработчике, и отклонение отp
должно пропускать.then()
обработчик.Используйте вторую схему, если вы хотите иметь возможность отлавливать ошибки в исходном обещании
p
и, возможно, (в зависимости от условий) разрешить цепочке обещаний продолжать работу в разрешенном состоянии, таким образом выполняя.then()
обработчик.Другой вариант
Есть еще один вариант использования обоих обратных вызовов, который вы можете передать,
.then()
как в:Это гарантирует, что будет вызван только один из
fn1
илиfn2
. Еслиp
разрешится, тоfn1
будет вызван. Еслиp
откажется, тоfn2
будет называться. Никакое изменение результата неfn1
может заставить васfn2
ответить, или наоборот. Итак, если вы хотите быть абсолютно уверены, что вызывается только один из двух ваших обработчиков, независимо от того, что происходит в самих обработчиках, вы можете использоватьp.then(fn1, fn2)
.источник
.then()
и.catch()
, на который вы отвечаете. Кроме того, вы дадите несколько советов о том, когда использовать какой порядок, где, я думаю, уместно упомянуть третий вариант, а именно передачу обработчика успеха и ошибки в .then () . В этом случае будет вызвано не более одного обработчика.Promise.reject(new Error("F")).then(x => x).catch(e => {console.log(e); return [1]}).then(console.log)
иPromise.resolve([2]).then(x => x).catch(e => [1]).then(console.log)
.then(this.setState({isModalOpen: false}))
. Вы не передаете ссылку на функцию,.then()
чтобы код в скобках выполнялся немедленно (до разрешения обещания). Так и должно быть.then(() => this.setState({isModalOpen: false}))
.Ответ jfriend00 отличный, но я подумал, что было бы неплохо добавить аналогичный синхронный код.
аналогичен синхронному:
Если
iMightThrow()
не бросит,then()
будет вызван. Если он бросает (илиthen()
сам бросает), тоhandleCatch()
будет вызван. Обратите внимание на то, чтоcatch
блок не контролирует,then
вызывается он или нет .С другой стороны,
аналогичен синхронному:
В этом случае, если
iMightThrow()
не бросит, тоthen()
выполнит. Если он выбрасывает, тогда нужно будетhandleCatch()
решить,then()
вызывается ли , потому что, еслиhandleCatch()
повторяется, тоthen()
не будет вызываться, поскольку исключение будет брошено вызывающему немедленно. ЕслиhandleCatch()
удастся изящноthen()
решить проблему, будет вызван.источник
then()
вfinally{...}
then()
вfinally{...}
, не будет его неправильно назвать , даже еслиhandleCatch()
броски? Имейте в виду, что моей целью было показать аналогичный синхронный код, а не предлагать различные способы обработки исключений