redux-saga 中的承诺
Promises in redux-saga
我发现了同样的问题 ,但没有我正在寻找的正确答案。
我正在开发一个带有 CRUD 操作的简单应用程序。在编辑页面上,安装组件 (componentDidMount()
) 后,应用会调度一个操作来检索特定的 post 详细信息:
dispatch({ type: FETCH_POST, id: 'post-id' })
我正在使用 redux-saga 并希望上面的调用 return 一个 Promise 以便我可以访问 API 响应。
现在,在没有 callback/Promise 的情况下,我最终在商店中定义了一个新状态(例如 post_edited
),并且 connect/map 将其 connect/map 用于编辑页面组件中的道具。
处理这种情况的最佳方法是什么?
能否提供有关您的问题的更多信息?我不确定我是否正确理解你的问题,但通常的做法是:
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);
}
有一个包完全按照 OP 的要求执行,即安排 dispatch()
可以 return 一个承诺:@adobe/redux-saga-promise
使用它,您可以通过以下方式定义 "promise action" 创建者:
import { createPromiseAction } from '@adobe/redux-saga-promise'
export const fetchPostAction = createPromiseAction('FETCH_POST')
一个"promise action"的dispatch()
将return一个承诺:
await dispatch(fetchPostAction({ id: 'post-id' }))
传奇可能看起来像:
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);
}
它会用 apiCallToFetchPost
编辑的值 return 解决承诺,如果 apiCallToFetchPost
抛出错误则拒绝。它还使用可以在 reducer 中访问的 resolution/rejection 调度辅助操作。该软件包提供 middleware you have to install 使其工作。
(免责声明,我是作者)
另一个解决方案
onSubmit: (values) => {
return new Promise((resolve, reject) => {
dispatch(someActionCreator({ values, resolve, reject }))
});
}
在传奇中:
function* saga() {
while (true) {
const { payload: { values, resolve, reject } } = yield take(TYPE)
// use resolve() or reject() here
}
}
参考:https://github.com/redux-saga/redux-saga/issues/161#issuecomment-191312502
我是 @teroneko/redux-saga-promise. It was initially forked from @adobe/redux-saga-promise 的开发者,但现在它已经完全改造为使用 @reduxjs/toolkit 的 createAction 来支持 TypeScript。
为了与@ronen 的示例保持联系,这里是 TypeScript 等效项。
创建承诺操作(创建者):
import { promiseActionFactory } from '@teroneko/redux-saga-promise'
export const fetchPostAction = promiseActionFactory<void>().create<{ id: string }>('FETCH_POST')
发送 promise 动作(来自创建者):
// promiseMiddleware is required and must be placed before sagaMiddleware!
const store = createStore(rootReducer, {}, compose(applyMiddleware(promiseMiddleware, sagaMiddleware)))
await store.dispatch(fetchPostAction({ id: 'post-id' }))
到 resolve/reject promise 操作(来自 saga):
import { call, takeEvery } from 'redux-saga/effects'
import { implementPromiseAction } from '@teroneko/redux-saga-promise'
import { fetchPostAction } from './actions'
function * fetchPostSaga(action: typeof fetchPostAction.types.triggerAction) {
yield call(implementPromiseAction, action, function * () {
const { id } = action.payload
return yield call(apiCallToFetchPost, id)
})
// or for better TypeScript-support
yield call(fetchPostAction.sagas.implement, action, function * () {
const { id } = action.payload
return yield call(apiCallToFetchPost, id)
})
}
export function * rootSaga() {
yield takeEvery(fetchPostAction, fetchPostSaga);
}
所以这是怎么回事?
- promise 操作(创建者)被创建
- 创建承诺操作(来自创建者)并且
- 已派送至商店。
- 然后 promise 操作被转换为可等待的 promise 操作,其中它的延迟版本被保存到元 属性 中。该动作立即返回并且
- 传递给 saga 中间件。
- 现在可等待的承诺操作有资格在 implementPromiseAction 中使用,除了解决或拒绝保存在可等待承诺操作的元 属性 中的延迟承诺外,别无他法。
有关更多功能和高级用例,请参阅 README。
我发现了同样的问题
我正在开发一个带有 CRUD 操作的简单应用程序。在编辑页面上,安装组件 (componentDidMount()
) 后,应用会调度一个操作来检索特定的 post 详细信息:
dispatch({ type: FETCH_POST, id: 'post-id' })
我正在使用 redux-saga 并希望上面的调用 return 一个 Promise 以便我可以访问 API 响应。
现在,在没有 callback/Promise 的情况下,我最终在商店中定义了一个新状态(例如 post_edited
),并且 connect/map 将其 connect/map 用于编辑页面组件中的道具。
处理这种情况的最佳方法是什么?
能否提供有关您的问题的更多信息?我不确定我是否正确理解你的问题,但通常的做法是:
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);
}
有一个包完全按照 OP 的要求执行,即安排 dispatch()
可以 return 一个承诺:@adobe/redux-saga-promise
使用它,您可以通过以下方式定义 "promise action" 创建者:
import { createPromiseAction } from '@adobe/redux-saga-promise'
export const fetchPostAction = createPromiseAction('FETCH_POST')
一个"promise action"的dispatch()
将return一个承诺:
await dispatch(fetchPostAction({ id: 'post-id' }))
传奇可能看起来像:
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);
}
它会用 apiCallToFetchPost
编辑的值 return 解决承诺,如果 apiCallToFetchPost
抛出错误则拒绝。它还使用可以在 reducer 中访问的 resolution/rejection 调度辅助操作。该软件包提供 middleware you have to install 使其工作。
(免责声明,我是作者)
另一个解决方案
onSubmit: (values) => {
return new Promise((resolve, reject) => {
dispatch(someActionCreator({ values, resolve, reject }))
});
}
在传奇中:
function* saga() {
while (true) {
const { payload: { values, resolve, reject } } = yield take(TYPE)
// use resolve() or reject() here
}
}
参考:https://github.com/redux-saga/redux-saga/issues/161#issuecomment-191312502
我是 @teroneko/redux-saga-promise. It was initially forked from @adobe/redux-saga-promise 的开发者,但现在它已经完全改造为使用 @reduxjs/toolkit 的 createAction 来支持 TypeScript。
为了与@ronen 的示例保持联系,这里是 TypeScript 等效项。
创建承诺操作(创建者):
import { promiseActionFactory } from '@teroneko/redux-saga-promise'
export const fetchPostAction = promiseActionFactory<void>().create<{ id: string }>('FETCH_POST')
发送 promise 动作(来自创建者):
// promiseMiddleware is required and must be placed before sagaMiddleware!
const store = createStore(rootReducer, {}, compose(applyMiddleware(promiseMiddleware, sagaMiddleware)))
await store.dispatch(fetchPostAction({ id: 'post-id' }))
到 resolve/reject promise 操作(来自 saga):
import { call, takeEvery } from 'redux-saga/effects'
import { implementPromiseAction } from '@teroneko/redux-saga-promise'
import { fetchPostAction } from './actions'
function * fetchPostSaga(action: typeof fetchPostAction.types.triggerAction) {
yield call(implementPromiseAction, action, function * () {
const { id } = action.payload
return yield call(apiCallToFetchPost, id)
})
// or for better TypeScript-support
yield call(fetchPostAction.sagas.implement, action, function * () {
const { id } = action.payload
return yield call(apiCallToFetchPost, id)
})
}
export function * rootSaga() {
yield takeEvery(fetchPostAction, fetchPostSaga);
}
所以这是怎么回事?
- promise 操作(创建者)被创建
- 创建承诺操作(来自创建者)并且
- 已派送至商店。
- 然后 promise 操作被转换为可等待的 promise 操作,其中它的延迟版本被保存到元 属性 中。该动作立即返回并且
- 传递给 saga 中间件。
- 现在可等待的承诺操作有资格在 implementPromiseAction 中使用,除了解决或拒绝保存在可等待承诺操作的元 属性 中的延迟承诺外,别无他法。
有关更多功能和高级用例,请参阅 README。