redux-saga

242 阅读2分钟
  1. redux-saga 是一个 redux 的中间件,而中间件的作用是为 redux 提供额外的功能。
  2. saga的工作原理
sages 采用 Generator 函数来 yield Effects(包含指令的文本对象)
Generator 函数的作用是可以暂停执行,再次执行的时候从上次暂停的地方继续执行
Effect 是一个简单的对象,该对象包含了一些给 middleware 解释执行的信息。
你可以通过使用 effects API 如 fork,call,take,put,cancel 等来创建 Effect。 redux-saga
  1. redux-saga分类
worker saga 做左右的工作,如调用API,进行异步请求,获取异步封装结果
watcher saga 监听被dispatch的actions,当接受到action或者知道其被触发时,调用worker执行任务
root saga 立即启动saga的唯一入口

  1. api
/**
 * Fork 执行一个非阻塞操作
 * Take 暂停并等待action到达
 * Race 同步执行多个 effect,然后一旦有一个完成,取消其他 effect。
 * Call 调用一个函数,如果这个函数返回一个 promise ,那么它会阻塞 saga,直到promise成功被处理。
 * Put 触发一个Action。
 * Select 启动一个选择函数,从 state 中获取数据。
 * takeLatest 意味着我们将执行所有操作,然后返回最后一个(the latest one)调用的结果。如果我们触发了多个时间,它只关注最后一个(the latest one)返回的结果。
 * takeEvery 会返回所有已出发的调用的结果。
 */
  1. 写一个简单的saga例子,方便记忆
1.action-types
export const INCREASE = 'increase'
export const INCREASE_ASYNC = 'increase_async'
2.actions.js
import * as types from './action-types'
export default {
  increment(i) {
    return { type: types.INCREASE_ASYNC }
  },
  decrease(i) {
    return { type: types.DECREASE, data: 3 }
  }
}
3.index.js
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import reducer from './reducer'
import { rootSaga } from './saga'

let sagaMiddleware = createSagaMiddleware()
const store = createStore(reducer, applyMiddleware(sagaMiddleware))
sagaMiddleware.run(rootSaga, store)

export default store
reducer.js
import * as types from './action-types'

export default function(state = { count: 0 }, action) {
  switch (action.type) {
    case types.INCREASE:
      return { count: state.count + action.data }
    default:
      return { ...state }
  }
}

saga.js
import { takeEvery, put, call, fork, take, all } from 'redux-saga/effects'

import * as types from './action-types'

export function* increment() {
  // yield call(delay, 1000)
  yield put({ type: types.INCREASE, data: 3 })
}

export function* watchIncrement() {
  while (true) {
    yield take(types.INCREASE_ASYNC)
    yield increment()
  }
}

export function* rootSaga() {
  yield fork(watchIncrement);
}