• redux-saga 异步流


    前言

    React的作用View层次的前端框架,自然少不了很多中间件(Redux Middleware)做数据处理, 而redux-saga就是其中之一,目前这个中间件在网上的资料还是比较少,估计应用的不是很广泛,但是如果使用得当,将会事半功倍的效果,下面仔细介绍一个这个中间件的具体使用流程和应用场景。

    redux-saga简介

    Redux-saga是Redux的一个中间件,主要集中处理react架构中的异步处理工作,被定义为generator(ES6)的形式,采用监听的形式进行工作。

    redux-saga安装

    使用npm进行安装:

    npm install --save redux-saga

    或者使用yarn:

    yarn add redux-saga

    redux-saga常用方法解释

    redux Effects

    Effect 是一个 javascript 对象,可以通过 yield 传达给 sagaMiddleware 进行执行在, 如果我们应用redux-saga,所有的 Effect 都必须被 yield 才会执行。

    举个例子,我们要改写下面这行代码:

    yield fetch(url);

    应用saga:

    yield call(fetch, url)

    take

    等待 dispatch 匹配某个 action 。

    比如下面这个例子:

    ....
    while (true) {
      yield take('CLICK_Action');
      yield fork(clickButtonSaga);
    }
    ....

    put

    触发某个action, 作用和dispatch相同:

    yield put({ type: 'CLICK' });

    具体的例子:

    import { call, put } from 'redux-saga/effects'
    
    export function* fetchData(action) {
       try {
          const data = yield call(Api.fetchUser, action.payload.url)
          yield put({type: "FETCH_SUCCEEDED", data})
       } catch (error) {
          yield put({type: "FETCH_FAILED", error})
       }
    }

    select

    作用和 redux thunk 中的 getState 相同。通常会与reselect库配合使用。

    call

    有阻塞地调用 saga 或者返回 promise 的函数,只在触发某个动作。

    takeEvery

    循环监听某个触发动作,我们通常会使用while循环替代。

    import { takeEvery } from 'redux-saga/effects'
    
    function* watchFetchData() {
      yield takeEvery('FETCH_REQUESTED', fetchData)
    }

    takeLatest

    对于触发多个action的时候,只执行最后一个,其他的会自动取消。

    import { takeLatest } from 'redux-saga/effects'
    
    function* watchFetchData() {
      yield takeLatest('FETCH_REQUESTED', fetchData)
    }

    fork 和 cancel

    通常fork 和 cancel配合使用, 实现非阻塞任务,take是阻塞状态,也就是实现执行take时候,无法向下继续执行,fork是非阻塞的,同样可以使用cancel取消一个fork 任务。

    function* authorize(user, password) {
      try {
        const token = yield call(Api.authorize, user, password)
        yield put({type: 'LOGIN_SUCCESS', token})
      } catch(error) {
        yield put({type: 'LOGIN_ERROR', error})
      }
    }
    
    function* loginFlow() {
      while(true) {
        const {user, password} = yield take('LOGIN_REQUEST')
        yield fork(authorize, user, password)
        yield take(['LOGOUT', 'LOGIN_ERROR'])
        yield call(Api.clearItem('token'))
      }
    }

    上面例子中,当执行

    yield fork(authorize, user, password)

    的同时,也执行了下面代码,进行logout的监听操作。

    yield take(['LOGOUT', 'LOGIN_ERROR'])

    redux-saga使用案例

    引入saga:

    import { call, put, take, select } from 'redux-saga/effects';

    创建任务:

    /**
     * Created by Richard on 1/11/17.
     */
    import { call, put, take, select } from 'redux-saga/effects';
    import { get, getWordUrl } from '../../utils/api';
    import {successFetchData } from './WordAction';
    
    export default function* wordFlow() {
        try {
             const data = yield call(get, getWordUrl());
             yield put(successFetchData(data));
        } catch (e){
    
        }
    }

    创建saga:

    import { fork } from 'redux-saga/effects';
    import wordFlow from './containers/word-view/WordSaga';
    
    export default function* rootSaga() {
      yield [
        fork(wordFlow)
      ];
    }

    与redux中间件进行整合:

    /**
     * Created by Richard on 12/29/16.
     */
    import { applyMiddleware, createStore, compose } from 'redux';
    
    import createSagaMiddleware from 'redux-saga';
    
    import reducers from '../reducers';
    
    import sagas from '../sagas';
    
    //创建saga middleware
    const sagaMiddleware = createSagaMiddleware();
    
    const middlewares = compose(applyMiddleware(sagaMiddleware)autoRehydrate());
    
    export default function configureStore() {
            const store = createStore(reducers, undefined, middlewares);
            //运行所有已经注册的saga
            sagaMiddleware.run(sagas);
            return store;
    }

    下面就可以正常监听状态了。

    redux-saga的优势

    传统意义讲,我们很多业务逻辑要在action中处理,所以会导致action的处理比较混乱,难以维护,而且代码量比较大,如果我们应用redux-saga会很大程度上简化代码, redux-saga 本身也有良好的扩展性, 非常方便的处理各种复杂的异步问题

  • 相关阅读:
    移动端图片按比例裁剪
    bootstrap悬停下拉菜单显示
    videojs兼容ie8
    ie浏览器不支持多行隐藏显示省略号
    rem和px
    浏览器默认返回,页面刷新
    centos src compile gcc 7.3
    docker与gosu
    centos 安装 kernel
    docker proxy
  • 原文地址:https://www.cnblogs.com/crazycode2/p/8975673.html
Copyright © 2020-2023  润新知