[英]Why can't I dispatch an action when a promise resolves inside Redux middleware?
Background背景
I am writing a piece of Redux middleware that makes an axios request and uses Cheerio to parse the result.我正在编写一段 Redux 中间件,它发出 axios 请求并使用 Cheerio 解析结果。
Problem问题
When the Axios promise resolves and I try to dispatch a fulfilled action the action does not show up in the store's action log in the test.当 Axios 承诺解决并且我尝试分派一个已完成的操作时,该操作不会出现在测试中商店的操作日志中。
Middleware中间件
function createMiddleware() {
return ({ dispatch, getState }) => next => action => {
if (isCorrectAction(action)===true){
const pendingAction = {
type: `${action.type}_PENDING`,
payload: action.payload
}
dispatch(pendingAction)
axios.get(action.payload.url)
.then(response => {
let $ = cheerio.load(response.data)
let parsedData = action.payload.task($)
const fulfilledAction = {
type: `${action.type}_FULFILLED`,
payload: {
parsedData
}
}
dispatch(fulfilledAction) // dispatch that is problematic
})
.catch( err => {
});
}
return next(action);
}
}
Test that fulfilled action is dispatched fails已完成的动作被分派的测试失败
it('should dispatch ACTION_FULFILLED once', () => {
nock("http://www.example.com")
.filteringPath(function(path) {
return '/';
})
.get("/")
.reply(200, '<!doctype html><html><body><div>text</div></body></html>');
const expectedActionTypes = ['TASK', 'TASK_PENDING', 'TASK_FULFILLED']
// Initialize mockstore with empty state
const initialState = {}
const store = mockStore(initialState)
store.dispatch(defaultAction)
const actionsTypes = store.getActions().map(e => e.type)
expect(actionsTypes).has.members(expectedActionTypes);
expect(actionsTypes.length).equal(3);
});
Solution - Promise needs to be returned in the mocha test解决方案——在 mocha 测试中需要返回 Promise
The solution is to rewrite the mocha test so that the promise is returned.解决方案是重写 mocha 测试,以便返回承诺。 I mistakenly thought that by using nock to intercept the HTTP request that the promise would become synchronous.
我错误地认为通过使用nock拦截HTTP请求,promise会变成同步的。
The working test looks like:工作测试看起来像:
it('should dispatch ACTION_FULFILLED once', () => {
nock("http://www.example.com")
.filteringPath(function(path) {
return '/';
})
.get("/")
.reply(200, '<!doctype html><html><body><div>text</div></body></html>');
const store = mockStore();
return store.dispatch(defaultScrapingAction)
.then(res => {
const actionsTypes = store.getActions().map(e => e.type)
expect(actionsTypes).has.members(expectedActionTypes);
expect(actionsTypes.length).equal(3);
})
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.