美文网首页
Redux-saga

Redux-saga

作者: 月肃生 | 来源:发表于2018-10-09 14:35 被阅读12次

    前言

    在阅读此文章前,需要你会ES6的Generator函数,另外redux中间件的原理也希望你能初步了解。

    为什么会有redux-saga

    中间件用过redux-thunk,也用过redux-promise-middleware,原理都很简单。

    thunk就是简单的action作为函数,在action进行异步操作,发出新的action。
    而promise只是在action中的payload作为一个promise,中间件内部进行处理之后,发出新的action。

    这两个简单也容易理解,但是当业务逻辑多且复杂的时候会发生什么情况呢?我们的action越来越复杂,payload越来越长,当然我们可以分离开来单独建立文件去处理逻辑,但是实质上还是对redux的action和reducer进行了污染,让它们变得不纯粹了,action就应该作为一个信号,而不是处理逻辑,reducer里面处理要好一些,但是同样会生出几个多余的action类型进行处理,而且也只能是promise,不能做复杂的业务处理。

    redux-saga将进行异步处理的逻辑剥离出来,单独执行,利用generator实现异步处理。
    一个计数器示例

    redux-saga

    1. saga任务,新建文件处理业务逻辑,使用generator,redux-saga提供很多函数方便处理,put发出action,takeEvery监听action,takeLatest只执行最后一次action,call执行函数,并且可以获取promise的数据
    import {delay} from 'redux-saga'
    import {put, takeEvery, all, call} from 'redux-saga/effects'
    
    export function* hello() {
      console.log('hello saga!')
    }
    const ajax = () => new Promise(resolve=>setTimeout(()=>resolve(99), 4000))
    export function* incrementAsync() {
      let data = yield call(ajax)
      yield put({type: 'INCREMENT'})
    }
    
    export function* watchIncrementAsync() {
      yield takeEvery('INCREMENT', ()=>console.log('+1'))
      yield takeEvery('INCREMENT_ASYNC', incrementAsync)
    }
    
    export default function* rootSaga() {
      yield all([
        hello(),
        watchIncrementAsync()
      ])
    }
    
    1. 启动generator
    const sagaMiddleware = createSagaMiddleware()
    const store = createStore(
      reducer,
      applyMiddleware(sagaMiddleware)
    )
    sagaMiddleware.run(rootSaga)
    

    后话

    antd的dva是对redux-saga的一个很好的实现。

    相关文章

      网友评论

          本文标题:Redux-saga

          本文链接:https://www.haomeiwen.com/subject/prkeaftx.html