阅读 1232

redux-thunk和redux-saga的区别

redux数据流向

首先dispatch触发一个action,然后由store自动调用reducers,返回新的state,当state改变时,store就会调用监听函数,进而视图发生改变。

redux不支持异步action

当我们在action里面调用异步操作时,如下:

export function decreaseAsyncCount() {
  return () => {
    // 异步操作
    setTimeout(function () {
      store.dispatch(inscreaseCount());
    }, 1000);
  };
}
复制代码

结果会报如下错误:

一般我们的解决方案是使用中间件,而redux-thunk和redux-saga被讨论最多。

redux-thunk和redux-sage区别

在社区里面,这两种是使用并且讨论最多的两个插件。

redux-thunk

怎么引用和关联redux-thunk我不介绍了,网上有很多资料。这里直接说重点,先看下面的代码:

export function decreaseAsyncCount() {
  return (dispatch) => {
    // 异步操作
    setTimeout(function () {
      dispatch(inscreaseCount());
    }, 1000);
  };
}
复制代码

上面的代码是使用redux-thunk的代码,当我们返回的是函数时,store会帮我们调用这个返回的函数,并且把dispatch暴露出来供我们使用。对于redux-thunk的整个流程来说,它是等异步任务执行完成之后,我们再去调用dispatch,然后去store去调用reduces。,如下图:

redux-saga

这里我也直接说整点,先看下面代码:

import { takeEvery } from 'redux-saga'
import { call, put } from 'redux-saga/effects'

function* asyncGetData() {
  yield* takeEvery('asyncGetData', asyncGetData)
}

function asyncGetData(action){
  try {
      // 执行函数
      const data = yield call(Api.fetchUser, action.payload.url);
      // 相当于dispatch
      yield put({type: "FETCH_SUCCEEDED", data});
   } catch (error) {
      yield put({type: "FETCH_FAILED", error});
   }
}
复制代码

上面的代码是使用了redux-saga的代码,当我们dispatch的action类型不在reducer中时,redux-saga的监听函数takeEvery就会监听到,等异步任务有结果就执行put方法,相当于dispatch,再一次触发dispatch。对于redux-saga的整个流程来说,它是等执行完action和reducer之后,判断reducer中有没有这个action,如下图:

所以总结来看,redux-thunk和redux-saga处理异步任务的时机不一样。对于redux-saga,相对于在redux的action基础上,重新开辟了一个 async action的分支,单独处理异步任务

saga 自己基本上完全弄了一套 asyc 的事件监听机制,代码量大大增加,从我自己的使用体验来看 redux-thunk 更简单,和 redux 本身联系地更紧密。尤其是整个生态都向函数式编程靠拢的今天,redux-thunk 的高阶函数看上去更加契合这个闭环。

文章分类
前端
文章标签