Как продолжить тот же поток, когда узел является отклоненным обещанием?

Я использую redux-observable для отправки действия с преобразованием некоторого результата обещания.

Допустим, у меня есть такой вызов API:

const fetchSomething = () => callAndReturnPromise('some-endpoint')

Используя эти создатели действий:

const fetchSomethingSuccess = response => ({ type: 'SUCCESS', payload: response })
const fetchSomethingError = error => ({ type: 'ERROR', payload: error })

Я могу создавать действия для обоих случаев, когда fetchSomething разрешено или отклонено.

Я хочу, чтобы мой эпик выполнял все действия FETCH и использовал функцию fetchSomething, чтобы поместить новый узел с разрешенным или отклоненным значением обещания с использованием соответствующих создателей действий.

Моя эпопея выглядит так:

const fetchSomethingEpic = action$ =>
    action$
        .ofType('FETCH')
        .switchMap(() => 
            Observable
                .fromPromise(fetchSomething())
                .map(fetchSomethingSuccess)
                .catch(error => Observable.of(fetchSomethingError(error)))
    );

Проблема в том, что он перестает работать при возникновении ошибки.

Когда обещание, сгенерированное fetchSomething, выполняется, все идет нормально, отправляется новое действие с преобразованием, переданным с помощью map. Но когда обещание отклоняется, после FETCH никаких действий не отправляется.

--

Больше информации

callAndReturnPromise('some-endpoint) выглядит так:

const callAndReturnPromise = endpoint => new Promise((resolve, reject) => {
    fetch(endpoint)
        .then(response => {
            if (checkIsCool(response)) {
                resolve(response);
            } else {
                reject(response)
            }
    })
})

После отладки я получаю что-то вроде этого, давайте назовем действия в потоке с помощью F, S, E (выборка, успех и ошибка)

----F----S------F-------F------S
                     ^ there occurred an error but no action was sent

person cnexans    schedule 14.06.2017    source источник


Ответы (1)


Проблема в том, что он перестает работать при возникновении ошибки

Можете быть более конкретными? Что именно перестает работать и как узнать? Есть ли ошибки? и т.п.


Я сразу вижу проблему, но это была бы ошибка синтаксического анализа, поэтому, скорее всего, это просто опечатка в вашем вопросе: для возврата объекта из функции стрелки требуется заключить фигурные скобки в круглые скобки.

// before
const fetchSomethingSuccess = response => { type: 'SUCCESS', payload: response }
const fetchSomethingError = error => { type: 'ERROR', payload: error }

// after
const fetchSomethingSuccess = response => ({ type: 'SUCCESS', payload: response })
const fetchSomethingError = error => ({ type: 'ERROR', payload: error })

Хотя в этом конкретном случае это была бы ошибка синтаксического анализа, есть случаи, когда он будет фактически анализировать как блок с помеченный оператор, который для многих очень сбивает с толку.

например это полностью допустимый JavaScript и не является ошибкой синтаксического анализа:

const fetchSomethingSuccess = response => { type: 'SUCCESS' }

В этом случае { type: 'SUCCESS' } - это блок с посторонним помеченным оператором строки, оба из которых никоим образом не используются и не возвращаются. Думайте об этом функционально эквивалентном этому:

const fetchSomethingSuccess = function (response) {
  type: 'SUCCESS'; // extraneous
  // no return
};

На основе наших дальнейших разговоров и нового предоставленного кода:

Я добавил предоставленный код в jsbin, и, похоже, он работает так, как я ожидал, действие ERROR отправляется правильно. https://jsbin.com/rujemak/edit?js,output

person jayphelps    schedule 14.06.2017
comment
Извините, это была опечатка, позвольте мне исправить. Я только что обновил ответ, объясняющий, что происходит. Я не знаю, потому что ловушка находится внутри switchMap. - person cnexans; 14.06.2017
comment
@cnexans извините, человек все еще не ясно. При отклонении обещания никаких действий не выполняется, но есть ли ошибки в консоли? Что вы пытались отладить? Ваш код на самом деле выглядит правильно AFAICT, поэтому пробовали ли вы стандартные средства отладки, такие как Pause on Caught Exception, .do ({error: callback}) материал и т. Д. - person jayphelps; 14.06.2017
comment
Ваш код на 100% идентичен примеру? в противном случае, возможно, в вашем примере могут отсутствовать некоторые тонкости. - person jayphelps; 14.06.2017
comment
Я добавлю еще пару информации в вопрос, большое спасибо! - person cnexans; 15.06.2017
comment
Я думаю, это потому, что, когда обещание отклоняется, switchMap по какой-то причине останавливает подписку. - person cnexans; 15.06.2017
comment
@cnexans, когда вы заключаете обещание в fromPromise, если обещание отклоняет, оно переходит по наблюдаемому пути ошибки, которую catch ... поймает. - person jayphelps; 15.06.2017
comment
@cnexans обновил мой ответ, я добавил ваш код в jsbin, и он работает так, как я ожидал, jsbin .com / rujemak / edit? js, вывод - person jayphelps; 16.06.2017