Получить ответ действия как обещание (например, redux-thunk)

Я перехожу от redux-thunk к redux-saga, но обнаружил один недостаток.

С redux-thunk у меня был очень типичный способ «добавить запросы»:

try {
    downloadId = await dispatch(requestDownload('SOME_URL'));
} catch(ex) {
    console.log('download already existed, so request denied');
}

Это действие вернет обещание, которое я мог бы подождать. Функция request (requestDownload выше) либо удовлетворит запрос и разрешит с помощью downloadId, либо отклонит, если загрузка для этого SOME_URL уже существует.

Как я могу сделать это в редукс-саге? Кажется, действия не могут ничего вернуть.

Спасибо


person Noitidart    schedule 20.08.2017    source источник


Ответы (1)


В redux-saga вы используете не await, а yield в сочетании с effects.

Ваш код может выглядеть так:

// saga.js

import { call, put } from 'redux-saga/effects'
import { requestDownloadSucceeded, requestDownloadFailed } from './reducer.js'

function* downloadRequestedFlow() {
  try {
    const downloadId = yield call(requestDownload, 'SOME_URL')

    yield put(requestDownloadSucceeded(downloadId))
  } catch(error) {
    yield put(requestDownloadFailed(error))
  }
}


// reducer.js
...
export const requestDownloadSucceeded = downloadId => ({
  type: REQUEST_DOWNLOAD_SUCCEEDED,
  downloadId,
})

export const requestDownloadFailed = error => ({
  type: REQUEST_DOWNLOAD_FAILED,
  error,
})

Обратите внимание на функцию генератора с *, которая позволяет использовать yield. Здесь я также использую обычный шаблон REQUESTED, SUCCEEDED, FAILED.

Я надеюсь, что этот ответ был полезен.

person Alex    schedule 21.08.2017
comment
Спасибо @Alex, но мне нужно знать, был ли первоначальный dispatch(action) успешным. В redux-thunk мое действие завершится ошибкой, если isFetching/isDownloading верно, мое действие проверит state. - person Noitidart; 21.08.2017
comment
Ваш метод requestDownload возвращает обещание. Он делает запрос на обслуживание и разрешается с помощью downloadId и отклоняет с помощью error, который затем перехватывается в блоке catch. - person Alex; 21.08.2017
comment
Вау, совсем забыл принять это. Это действительно помогло мне понять саги. - person Noitidart; 13.02.2018