Первый затем для моего обещания возвращает обещание, даже если в отклоненном методе нет функции возврата

В приведенном ниже коде первый .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)
})

Передача второго аргумента в a.then(...) означает: "если a отклонен, вызовите эту функцию и верните (успешно) выполненное обещание, если не было выдано ни одной ошибки". Так что он работает именно так, как задумано. Если это не то поведение, которое вам нужно, вам не следует передавать второй аргумент в .then.

Felix Kling 26.09.2018 10:42
«Почему код не останавливается только на первом вызове then, поскольку метод reject не возвращает обещание?» Вы про reject? Ни resolve, ни reject не обещают. new Promise и .thenвсегда возвращают обещание. Обещание может находиться в трех разных состояниях: «отложено», если ни resolve, ни reject не были вызваны, «выполнено», если было вызвано resolve, или «отклонено», если был вызван reject. Функции, которые вы регистрируете через .then, вызываются, когда обещание входит в определенное состояние. То, что происходит в этих функциях, определяет состояние обещания, возвращаемого .then.
Felix Kling 26.09.2018 10:48

Взгляните на developer.mozilla.org/en-US/docs/Mozilla/… для получения дополнительной информации.

Felix Kling 26.09.2018 10:50
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
60
4

Ответы 4

У вас есть две ошибки в вашем коде, чтобы он работал так, как вы планировали, вам нужно написать его так:

    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 не распространяется должным образом на внешнюю цепочку обещаний).

Felix Kling 26.09.2018 10:46

просто есть общий подвох. Я обновил ваш код.

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 возвращает обещание, поэтому вам нужно связать его

Haim Houri 26.09.2018 10:36

Когда вызывается addTwo(res, 100), он переходит к следующему. Это связано только с тем, что если возникает ошибка, есть общий улов. Попробуйте запустить его один раз на своем локальном компьютере в обоих случаях, как правильном, так и неправильном.

Atishay Jain 26.09.2018 10:41

Думайте о цепочках обещаний как о двух цепочках - выполненных и отклоненных.

Кроме того, вы знаете, что .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)

Другие вопросы по теме