dva的model中effect调用其他effct方法为非阻塞的解决方案

dva model 中使用yield put 执行effects中另一个方法,发起请求,不会等这个请求执行完才执行下面的方法。

问题背景

问题描述

dva model 中使用yield put 执行effects中另一个方法,发起请求,不会等这个请求执行完才执行下面的方法。

 effects: {
    
    
    *effectAll({
    
     payload }, {
    
     put, call }) {
    
    
      console.log('effectAll-start')
      yield put({
    
     type: 'effect1' });
      yield put({
    
     type: 'effect2' });
      console.log('effectAll-end')
    },

    *effect1({
    
     payload }, {
    
     call }) {
    
    
      yield call(serviceB, payload);
      console.log('1111')
    },

    *effect2({
    
     payload }, {
    
     call }) {
    
    
      yield call(serviceB, payload);
      console.log('2222')
    }
  },

期望结果为

effectAll-start
1111
2222
effectAll-end

实际结果为

effectAll-start
effectAll-end
1111
2222

or

effectAll-start
effectAll-end
2222
1111

两种结果不同,哪个请求完成的快哪个在前面,非阻塞运行

问题解析

  • put是一个非阻塞的方法,put的使用效果和在外部使用dispatch是一样的;

  • 如果我们想等待1执行完再接下去执行2,那就需要阻塞运行;

put(action): 创建一个 Effect 描述信息,用来命令 middleware 向 Store 发起一个 action。 这个 effect 是非阻塞型的,并且所有向下游抛出的错误(例如在 reducer 中),都不会冒泡回到 saga 当中。

问题解决过程

  1. 查看dva官方文档,没有发现相关内容
  2. 搜索’'dva effect调用effect"发现两种解决方案,均为使用redux-saga

阻塞运行的解决方案

使用put.slove

put.resolve(action):类似 put,但 effect 是阻塞型的(如果从 dispatch 返回了 promise,它将会等待其结果),并且会从下游冒泡错误。

  effects: {
    
    
    *effectAll({
    
     payload }, {
    
     put, call }) {
    
    
      console.log('effectAll-start')
      yield put.resolve({
    
     type: 'effect1' });
      yield put.resolve({
    
     type: 'effect2' });
      console.log('effectAll-end')
    },

    *effect1({
    
     payload }, {
    
     call }) {
    
    
      yield call(serviceB, payload);
      console.log('1111')
    },

    *effect2({
    
     payload }, {
    
     call }) {
    
    
      yield call(serviceB, payload);
      console.log('2222')
    }
  },

使用take

 effects: {
    
    
    *effectAll({
    
     payload }, {
    
     put, call, take }) {
    
    
      console.log('effectAll-start')
      yield put({
    
     type: 'effect1' });
      yield take('effect1/@@end') //直到监听到结束才继续执行
      yield put.resolve({
    
     type: 'effect2' });
      yield take('effect2/@@end') //直到监听到结束才继续执行
      console.log('effectAll-end')
    },

    *effect1({
    
     payload }, {
    
     call }) {
    
    
      yield call(serviceB, payload);
      console.log('1111')
    },

    *effect2({
    
     payload }, {
    
     call }) {
    
    
      yield call(serviceB, payload);
      console.log('2222')
    }
  },

参考资料

redux-saga中文文档

扫描二维码关注公众号,回复: 12921262 查看本文章

feat: Support put.resolve to wait the effect to resolve

猜你喜欢

转载自blog.csdn.net/tianxintiandisheng/article/details/112475583