Promises in redux-saga

后端 未结 3 718
攒了一身酷
攒了一身酷 2021-02-14 12:26

I found the same question here, but without a proper answer I am looking for.

I am developing a simple application with CRUD operations. On the edit page, after the comp

相关标签:
3条回答
  • 2021-02-14 13:11

    Another solution

    onSubmit: (values) => {
      return new Promise((resolve, reject) => {
        dispatch(someActionCreator({ values, resolve, reject }))
      });
    }
    

    In saga:

    function* saga() {
      while (true) {
        const { payload: { values, resolve, reject } } = yield take(TYPE)
        // use resolve() or reject() here
      }
    }
    

    Reference: https://github.com/redux-saga/redux-saga/issues/161#issuecomment-191312502

    0 讨论(0)
  • 2021-02-14 13:16

    There's a package that does exactly what the OP requested, i.e. arranges that dispatch() can return a promise: @adobe/redux-saga-promise Using it, you define a "promise action" creator via:

    import { createPromiseAction } from '@adobe/redux-saga-promise'
    
    export const fetchPostAction = createPromiseAction('FETCH_POST')
    

    The dispatch() of a "promise action" will return a promise:

    await dispatch(fetchPostAction({ id: 'post-id' }))
    

    The saga might look like:

    import { call, takeEvery }        from 'redux-saga/effects'
    import { implementPromiseAction } from '@adobe/redux-saga-promise'
    
    import { fetchPostAction } from './actions'
    
    function * fetchPostSaga(action) {
      yield call(implementPromiseAction, action, function * () {
        const { id } = action.payload
        return yield call(apiCallToFetchPost, id)
      })
    }
    
    export function * rootSaga() {
      yield takeEvery(fetchPostAction, fetchPostSaga);
    }
    

    It will resolve the promise with the value returned by apiCallToFetchPost or reject if apiCallToFetchPost throws an error. It also dispatches secondary actions with the resolution/rejection that you can access in a reducer. The package provides middleware you have to install to make it work.

    (Disclaimer, I'm the author)

    0 讨论(0)
  • 2021-02-14 13:20

    Could you please provide more information about your issue? I'm not sure if I understand your issue properly, but the common practice is:

    API.js

    function apiCallToFetchPost(id) {
      return Promise.resolve({name: 'Test});
    }
    

    postSaga.js

    function* fetchPostSaga({id}) {
      try {
        const request = yield call(apiCallToFetchPost, id);
        // -> in post reducer we will save the fetched data for showing them later 
        yield put({type: FETCH_POST_SUCCESS, payload: request}); 
      } catch (error) {
        yield put({type: FETCH_POST_SUCCESS_FAILURE, error})
      }
    }
    
    export function* onBootstrap() {
      yield takeLatest(FETCH_POST, fetchPostSaga);
    }
    
    0 讨论(0)
提交回复
热议问题