В приведенном ниже коде первый .then (), связанный с функцией addTwo, вызывает метод reject, потому что я проверяю, являются ли типы a и b "choco", что невозможно.
Я ожидал, что вывод остановится на «у нас есть босс ошибки» без продолжения, поскольку метод reject, в отличие от метода разрешения, не имеет оператора «return addTwo».
Но вывод показывает, что код переходит к следующему вызову then, а вывод - «ответ второго сложения: undefined». Почему код не останавливается на первом вызове then, поскольку метод reject не возвращает обещание?
var addTwo = (a, b) => {
return new Promise((resolve, reject) => {
if (typeof a === choco && typeof b === choco){
resolve(a + b)
}else{
reject("a or b or both were not numbers")
}
})
}
addTwo(5, 6).then((res) => {
console.info("Answer of addition: " + res)
return addTwo(res, 100)
}, (err) => {
console.info("We have an error boss: " + err)
}).then((res) => {
console.info("Answer of second addition: " + res)
}, (err) => {
console.info("We have an error boss: " + err)
})reject? Ни resolve, ни reject не обещают. new Promise и .thenвсегда возвращают обещание. Обещание может находиться в трех разных состояниях: «отложено», если ни resolve, ни reject не были вызваны, «выполнено», если было вызвано resolve, или «отклонено», если был вызван reject. Функции, которые вы регистрируете через .then, вызываются, когда обещание входит в определенное состояние. То, что происходит в этих функциях, определяет состояние обещания, возвращаемого .then.
Взгляните на developer.mozilla.org/en-US/docs/Mozilla/… для получения дополнительной информации.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


У вас есть две ошибки в вашем коде, чтобы он работал так, как вы планировали, вам нужно написать его так:
var addTwo = (a, b) => {
return new Promise((resolve, reject) => {
if (typeof a === choco && typeof b === choco){
resolve(a + b)
}else{
reject("a or b or both were not numbers")
}
})
}
addTwo(5, 6).then((res) => {
console.info("Answer of addition: " + res);
return addTwo(res, 100);
}, (err) => {
console.info("We have an error boss: " + err);
throw err;
}).then((res) => {
res.then(res2) => {
console.info("Answer of second addition: " + res2);
}, (err) => {
console.info("We have an error boss: " + err);
throw err;
}})
Это кажется излишне сложным (и последний throw err не распространяется должным образом на внешнюю цепочку обещаний).
просто есть общий подвох. Я обновил ваш код.
addTwo(5, 6).then((res) => {
console.info("Answer of addition: " + res)
return addTwo(res, 100);
}).then((res) => {
console.info(res);
console.info("Answer of second addition: " + res)
}).catch((err) => {
console.info("We have an error boss: " + err)
})
addTwo возвращает обещание, поэтому вам нужно связать его
Когда вызывается addTwo(res, 100), он переходит к следующему. Это связано только с тем, что если возникает ошибка, есть общий улов. Попробуйте запустить его один раз на своем локальном компьютере в обоих случаях, как правильном, так и неправильном.
Думайте о цепочках обещаний как о двух цепочках - выполненных и отклоненных.
Кроме того, вы знаете, что .then принимает два аргумента .then(onFulfilled, onRejected) - если один из onFulfilled или onRejected не является функцией, он игнорируется.
.catch(fn) - это просто .then(null, fn)
В каждой из функций, выполняемых .then (либо onFulfilled, либо onRejected), если выдается ошибка, то следующим будет вызываться .then следующего onRejected - в противном случае onFulfilled будет вызываться следующим
Если какой-либо из аргументов .then не является функцией, .then игнорирует их - в случае, если onFulfilled не является функцией, .then вернет разрешенное обещание, которое принимает выполненное (разрешенное) значение - и в случае onRejected не являясь функцией, .then вернет отклоненное обещание, которое принимает отклоненное значение
Ваш код буквально (просто показывает возвращаемые значения, игнорируя console.infos)
addTwo(5, 6)
.then(res => addTwo(res, 100), err => undefined)
.then(res => undefined, err => undefined);
поскольку первая функция onRejected возвращает undefined, будет вызываться вторая функция .then(res=>
Как предлагается в другом ответе, в этом случае вам нужен один .catch
так
addTwo(5, 6)
.then((res) => {
console.info("Answer of addition: " + res)
return addTwo(res, 100)
})
.then((res) => {
console.info("Answer of second addition: " + res)
})
.catch((err) => {
console.info("We have an error boss: " + err)
});
Что есть - без console.infos
addTwo(5, 6)
.then(res => addTwo(res, 100), null)
.then(res => undefined, null)
.then(null, err => undefined);
поскольку первый и второй. тогда имеют значение NULL для onRejected, то есть не функция, "ошибка" течет вниз по цепочке отклоненных запросов, пока функция не будет "найдена".
С функциональным стилем и некоторыми помощниками вы можете решить эту проблему простым и легко читаемым способом:
import { curry } from 'crocks/helpers/curry'
// async functions always return promises
const addPromise = curry(async (a, b) => {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new Error("a or b or both were not numbers")
} else {
return a + b
}
})
const trace = tag => x => console.info(tag, x) || x
const handleError = err => console.info(`We have an error boss: ${err}`)
addPromise(5, 6)
.then(trace('Answer from First Addition'))
.then(addPromise(100))
.then(trace('Answer from Second Addition'))
.catch(handleError)
Передача второго аргумента в
a.then(...)означает: "еслиaотклонен, вызовите эту функцию и верните (успешно) выполненное обещание, если не было выдано ни одной ошибки". Так что он работает именно так, как задумано. Если это не то поведение, которое вам нужно, вам не следует передавать второй аргумент в.then.