[React] Create a queue of Ajax requests with redux-observable and group the results.

With redux-observable, we have the power of RxJS at our disposal - this means tasks that would otherwise be complicated and imperative, become simple and declarative. In this lesson we’ll respond to an action by queuing up 2 separate Ajax requests that will execute sequentially. Then we’ll group the results from both into an array and produce a single action from our epic that will save the data into the redux store

 

复制代码
// action

export const FETCH_STORIES = 'FETCH_STORIES';
export const FETCH_STORIES_FULFILLED = 'FETCH_STORIES_FULFILLED';

export function fetchStoriesAction(count = 5) {
  return {
    type: FETCH_STORIES,
    payload: count
  }
}

export function fetchStoriesFulfilledAction(stories) {
  return {
    type: FETCH_STORIES_FULFILLED,
    payload: stories
  }
}
复制代码

 

复制代码
// epics

import {Observable} from 'rxjs';
import {combineEpics} from 'redux-observable';
import {FETCH_STORIES, fetchStoriesFulfilledAction} from "../actions/index";

const topStories = `https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty`;
const url = (id) => `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`;

function fetchStoriesEpic(action$) {
  return action$.ofType(FETCH_STORIES)
    .switchMap(({payload}) => {
      return Observable.ajax.getJSON(topStories)
        // slice first 5 ids
        .map(ids => ids.slice(0, 5))
        // convert ids -> urls
        .map(ids => ids.map(url))
        // convert urls -> ajax
        .map(urls => urls.map(url => Observable.ajax.getJSON(url)))
        // execute 5 ajax requests
        .mergeMap(reqs => Observable.forkJoin(reqs))
        // results -> store
        .map(stories => fetchStoriesFulfilledAction(stories))
    })
}

export const rootEpic = combineEpics(fetchStoriesEpic);
复制代码

 

复制代码
import {FETCH_STORIES, FETCH_STORIES_FULFILLED} from "../actions/index";

const initialState = {
  stories: [],
  loading: false,
};

export function storiesReducer(state = initialState, action) {
  switch(action.type) {
    case FETCH_STORIES:
      return {
        stories: [],
        loading: true
      };
    case FETCH_STORIES_FULFILLED:
      return {
        stories: action.payload,
        loading: false
      };
    default: return state;
  }
}

export default storiesReducer;
复制代码

 

复制代码
// component

import React from 'react';
import {connect} from "react-redux";
import {fetchStoriesAction} from "../actions/index";

export function Stories(props) {
  if (props.loading) {
    return (
      <p>Please wait...</p>
    )
  }
  return (
    <div>
      <button type="button" onClick={props.loadStories}>Load top 5 stories</button>
      <StoryList stories={props.stories} />
    </div>
  )
}

function StoryList(props) {
  return (
    <ul>
      {props.stories.map(story =>
        <li key={story.id}>
          <a href={story.url}>{story.title}</a>
        </li>
      )}
    </ul>
  );
}

function mapState(state) {
  return state;
}

function mapDispatch(dispatch) {
  return {
    loadStories: () => dispatch(fetchStoriesAction())
  }
}

export default connect(mapState, mapDispatch)(Stories);
复制代码

 

posted @   Zhentiw  阅读(792)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2016-10-16 [AngularFire2] Pagination
点击右上角即可分享
微信分享提示