redux-saga

300 阅读2分钟

Saga 辅助函数

import {
    put,
    call,
    takeEvery,
    takeLatest,
    select,
    fork,
    all,
    throttle
} from "redux-saga/effects";

function* demo() {
    yield take(pattern); // 阻塞执行,直到匹配的action触发才恢复执行
    yield put(action); // 发起一个action, 非阻塞且下游出现的错误不会冒泡到saga中
    yield put.resolve(action); // 阻塞执行,发起一个action并等待结果
    yield call(fn, ...args); // 以args为参数调用fn函数
    yield call([this, fn], ...args); // 传递上下文this到fn
    yield call([this, "fnName"], ...args); // 调用对象this的方法
    yield cps(fn, ...args); // 以args为参数调用fn函数, fn(..args, callback) success: 执行callback(null, result) fail: callback(error)
    yield fork(fn, ...args); // 以args为参数非阻塞调用fn, 返回一个Task对象
    yield spawn(fn, ...args); // 以args为参数非阻塞调用fn, 返回一个Task对象, 分离分叉
    yield join(task /*...tasks*/); // 等待之前的分叉任务的结果
    yield cancel(task /*...tasks*/); // 取消之前的分叉任务
    yield select(selector, ...args); // 获取store中的state, yield select()获取整个store
    yield all([call(), call()]); // 同时执行多个任务

    // 高级API
    yield takeEvery(pattern, saga, ...args); // 派发action, 允许并发
    yield takeLatest(pattern, saga, ...args); // 派发action, 不允许并发, 自动取消已经触发但是还没结束的action
    yield takeLeading(pattern, saga, ...args); // 派发action, 派发之后阻塞执行,直到saga完成
    yield throttle(ms, pattern, saga, ...args); // 节流阀,在指定时间内只派发一次action
} 

说明

  • pattern: 空或*匹配所有的action, 函数将匹配pattern(action)为true的action, 字符串将匹配action.type, 数组将匹配数组的每一项;
  • saga: Generator 函数;
  • ...args: 传参,action为最后一个参数;
  • ms: 时间,单位为毫秒;
  • selector: Function - 一个 (state, ...args) => args 的函数。它接受当前 state 和一些可选参数,并返回当前 Store state 上的一部分数据

Task的方法:

  • isRunning(): 若任务还未返回或抛出一个错误则为true
  • isCancelled(): 若任务已被取消则为true
  • result(): 任务的返回值,若任务仍在运行中则为undefined
  • error(): 任务抛出的错误, 若任务仍在运行中则为undefined
  • done(): resolve 或者 reject
  • cancel(): 取消任务

取消异步函数:

import { CANCEL } from "redux-saga";
import { fork, cancel } from "redux-saga/effects";

function myApi() {
    const promise = myXhr();

    promise[CANCEL] = () => myXhr.abort();
    return promise;
}

function* mySaga() {
    const task = yield fork(myApi);

    // ... 过一会儿儿
    // 将会调用 myApi 上的 promise[CANCEL]
    yield cancel(task);
}