Javascript 并行多个ajax调用并在成功后调度redux操作将导致;未捕获错误:操作必须是普通对象;
我是rxjs和redux observable的新手。尝试创建一个epic,允许我执行多个并行ajax调用,并在成功时分派相应的操作:Javascript 并行多个ajax调用并在成功后调度redux操作将导致;未捕获错误:操作必须是普通对象;,javascript,reactjs,redux,rxjs,redux-observable,Javascript,Reactjs,Redux,Rxjs,Redux Observable,我是rxjs和redux observable的新手。尝试创建一个epic,允许我执行多个并行ajax调用,并在成功时分派相应的操作: const loadPosters = (action$) => action$.pipe( ofType(Types.LOAD_FILMS_SUCCESS), switchMap(({ films }) => forkJoin(films.map(film => ajax .getJSON(`https
const loadPosters = (action$) => action$.pipe(
ofType(Types.LOAD_FILMS_SUCCESS),
switchMap(({ films }) =>
forkJoin(films.map(film =>
ajax
.getJSON(`https://api.themoviedb.org/3/search/movie?query=${film.title}`)
.pipe(
map(response => {
const [result] = response.results;
const poster = `http://image.tmdb.org/t/p/w500/${result.poster_path}`;
return Creators.savePoster(film, poster);
})
),
))
),
);
Creators.savePoster()
是名为SAVE\u POSTER
的动作的动作创建者。但是,每当我运行应用程序时,都不会调度这样的操作。相反,我在浏览器控制台中收到一条错误消息:
未捕获错误:操作必须是普通对象。使用自定义中间件
用于异步操作
编辑
尝试了一个没有forkJoin
的简化版本,遗憾的是得到了相同的结果:
const loadPosters = (action$) => action$.pipe(
ofType(Types.INIT_SUCCESS),
mergeMap(({ films }) =>
films.map(film =>
ajax
.getJSON(`https://api.themoviedb.org/3/search/movie?query=${film.title}`)
.pipe(
map(response => {
const [result] = response.results;
const poster = `http://image.tmdb.org/t/p/w500/${result.poster_path}`;
console.log(Creators.savePoster(film, poster));
return Creators.savePoster(film, poster);
})
)
),
),
);
附录
仅供参考,我还有另一个epic,它执行一个简单的ajax调用,效果很好:
const loadFilms = action$ => action$.pipe(
ofType(Types.INIT_REQUEST),
mergeMap(() =>
ajax
.getJSON('https://star-wars-api.herokuapp.com/films')
.pipe(
map(response => Creators.initSuccess(response))
),
),
);
问题是我没有在我的内部映射中返回一个可观察的。更改:
return Creators.savePoster(film, poster);
到
让它工作
顺便说一下,如果与forkJoin
一起使用,也可以(在我的情况下更好)在解决所有请求后获取映射结果,并发送单个操作,而不是多个操作:
const loadPosters = (action$) => action$.pipe(
ofType(Types.INIT_SUCCESS),
mergeMap(({ films }) =>
forkJoin(
films.map(film =>
ajax
.getJSON(`https://api.themoviedb.org/3/search/movie?query=${film.title}`)
.pipe(
map(response => ({ film, response }))
)
),
)
),
mergeMap(data => {
const posters = data.reduce((acc, { film, response}) => ({
...acc,
[film.id]: `http://image.tmdb.org/t/p/w500/${response.results[0].poster_path}`,
}), {});
return of(Creators.savePosters(posters));
})
);
事实上,到目前为止,这是我最喜欢的解决方案。这很好,正是我想要的:)但是我对失败的ajax调用有一个问题,您知道如何为每个成功调用分配成功操作,并为失败的ajax响应分配有效响应和失败操作吗?我甚至试过联合测试,但没有成功!可能有线索吗?谢谢
const loadPosters = (action$) => action$.pipe(
ofType(Types.INIT_SUCCESS),
mergeMap(({ films }) =>
forkJoin(
films.map(film =>
ajax
.getJSON(`https://api.themoviedb.org/3/search/movie?query=${film.title}`)
.pipe(
map(response => ({ film, response }))
)
),
)
),
mergeMap(data => {
const posters = data.reduce((acc, { film, response}) => ({
...acc,
[film.id]: `http://image.tmdb.org/t/p/w500/${response.results[0].poster_path}`,
}), {});
return of(Creators.savePosters(posters));
})
);