前端
PythonJava运维数据库
状态管理
状态管理
  • 🖥️Redux Tookit
    • Introduction
      • 介绍
    • Tutorials
      • 🖥️快速开始
      • 🏐在TypeScript环境使用
    • Using Redux toolkit
      • 使用Immer编写Reducers
      • 性能与数据范式化
      • 异步逻辑与数据请求
      • Usage With TypeScript
    • API Refrence
      • Store Setup
        • configureStore
        • getDefaultMiddleware
        • Immutability Middleware
        • Serializability Middleware
        • Action Creator Middleware
        • createListenerMiddleware
        • createDynamicMiddleware
        • getDefaultEnhancers
        • autoBatchEnhancer
      • Reducer and Actions
        • createReducer
        • createAction
        • createSlice
        • createAsyncThunk
        • createEntityAdapter
        • combineSlices
      • Other
        • createSelector
        • Matching Utilities
    • RTX Query
      • RTK Query Overview
      • Comparson with Other Tools
      • Examples
      • Usage With TypeScript
      • Using RTK Query
        • Queries
        • Mutations
      • API Refrence
        • createApi
        • fetchBaseQuery
        • ApiProvider
        • setupListeners
        • Generated API Slices
          • Generated API Slices
          • Redux Integration
          • Endpoints
          • Code Splitting
          • Utilities
          • React Hooks
  • 🚚Redux-Saga
    • 入门
    • 基础概念
    • API
    • 技巧
  • 🚑React Redux
    • 安装
    • 教程
    • 使用 React Redux
    • API 参考
  • 🚕生态
    • Redux Persist
    • zustand
      • 使用 useShallow 防止重新渲染
由 GitBook 提供支持
在本页
  • 节流(Throtting)
  • 防抖动(Debouncing)

这有帮助吗?

  1. Redux-Saga

技巧

节流(Throtting)

你可以通过在监听的 Saga 里调用一个 delay 函数,针对一系列发起的 action 进行节流。 举个例子,假设用户在文本框输入文字的时候,UI 触发了一个 INPUT_CHANGED action:

import { throttle } from 'redux-saga/effects'

function* handleInput(input) {
  // ...
}

function* watchInput() {
  yield throttle(500, 'INPUT_CHANGED', handleInput)
}

通过throttle,watchInput不会在500ms内启动一个新的handleInput任务,但在相同时间内,它仍然接受最新的INPUT_CHANGED 到底层的 buffer,所以它会忽略所有的 INPUT_CHANGED action。 这确保了 Saga 在 500ms 这段时间,最多接受一个 INPUT_CHANGED action,并且可以继续处理 trailing action。

防抖动(Debouncing)

为了对action队列进行防抖动,可以在被fork的任务里放置一个delay。

/**
 * @description 查询用户列表
 */
export function* fetchUsers() {
    yield delay(500)
    const {list}: PagesResult<User> = yield call(fetchUsersApi);
    yield put(setUsers(list));
}

function* watchFetchUsers() {
    let fetchUserTask: Task | undefined;
    while (true) {
        yield take(fetchUsersSagaAction)
        if (fetchUserTask) {
            yield cancel(fetchUserTask)
        }
        fetchUserTask = yield fork(fetchUsers)
    }
}

function* watchFetchUsers() {
    let fetchUserTask: Task | undefined;
    while (true) {
        yield take(fetchUsersSagaAction)
        if (fetchUserTask) {
            yield cancel(fetchUserTask)
        }
        fetchUserTask = yield fork(fetchUsers)
    }
}

export default function* userSaga() {
    yield watchFetchUsers();
}

在上面的示例中,fetchUsersApi在执行之前等待了500ms。如果在此期间,接收到的fetchUsersSagaAction,由于fetchUsers被delay阻塞,所以在执行自己的逻辑之前会被watchFetchUsers所取消。

例如,在 React 严格模式下,通过该方式可有效减少重复的请求。

上面的例子还可以使用redux-saga的 takeLatest 重写:

/**
 * @description 查询用户列表
 */
export function* fetchUsers() {
    yield delay(500)
    const {list}: PagesResult<User> = yield call(fetchUsersApi);
    yield put(setUsers(list));
}

export default function* userSaga() {
    // 将取消当前执行的 fetchUsersSagaAction
    yield  takeLatest(fetchUsersSagaAction, fetchUsers);
}
上一页API下一页安装

最后更新于1年前

这有帮助吗?

🚚