Dva: 请问一下 effects 中 yield put() 是一个非阻塞过程,如何做到 effects 中阻塞调用另一个 effect.

创建于 2017-09-12  ·  12评论  ·  资料来源: dvajs/dva

Code to reproduce the issue: (请提供可复现的代码或者步骤)

Expected behavior: (预期的正常效果)

Actual behavior: (实际效果)

Versions of packages used: (哪个库的哪个版本出现的问题)

最有用的评论

put.resolve()是阻塞的

yield put.resolve({ type: 'addDelay', payload: { amount: 2 } });
const count = yield select(state => state.count);
yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } });

put.resolve()就是阻塞的,详情见redux-saga API

所有12条评论

dva@2 已经提供了相应的例子,https://github.com/sorrycc/blog/issues/48

yield put({ type: 'addDelay', payload: { amount: 2 } });
yield take('addDelay/@<strong i="8">@end</strong>');
const count = yield select(state => state.count);
yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } });

https://github.com/redux-saga/redux-saga/issues/744
你可以看一下这里的解决方案。
直接用call 去阻塞调用你的那个effect。

但是在dva里面有一个问题,就是你要怎么获取你到你想调用的那个effect方法,因为dva里面的effect方法是写在model里面的,你自己想想看有没有什么方法从model里面获取目标方法,然后用call去调用吧。

@nihgwu

effect 前后会额外触发 /@<strong i="6">@start</strong> 和 /@<strong i="7">@end</strong> 的 action,

请问这段代码是saga里面封装的吗??我在dva的源码里面看不到有哟。可以告诉我这段源码的地址吗?

@hopperhuang 在 dva-core 里面

@hopperhuang dva 中的 effect 是写在 model 中的,我正是为这事儿烦,不知道如何取出来。看了 @nihgwu 的方法,我觉得是正解,先调用,然后立即 take 阻塞接收。

注意版本。我不知道大大提出解决方案是基于dva2,0的还是基于saga都试用的。dva1.0的源码里面,并没有对调用put之前和之后的事件进行一个封装,你可以问问大大,看看你自己的版本能不能适用该解决方案。

-----原始邮件-----
发件人: "pingsoli" [email protected]
发送时间: ‎2017/‎9/‎12 22:24
收件人: "dvajs/dva" [email protected]
抄送: "hopperhuang" [email protected]; "Mention" [email protected]
主题: Re: [dvajs/dva] 请问一下 effects 中 yield put() 是一个非阻塞过程,如何做到 effects 中阻塞调用另一个 effect. (#1212)

@hopperhuang dva 中的 effect 是写在 model 中的,我正是为这事儿烦,不知道如何取出来。看了 @nihgwu 的方法,我觉得是正解,先调用,然后立即 take 阻塞接收。

You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

为什么要阻塞put,请问这里的应用场景是什么

为什么要阻塞put,请问这里的应用场景是什么

如果 put 的 action 是被 saga (在 dva 中是 effect) 处理的,那么 yield put 返回时,对应的 saga/effect 还没有完成执行(redux-saga 的 scheduler 会将其入队,稍后再逐步调度),这样就不满足某些状态流程的阻塞要求。

如果我没有记错的话,put action 被 reducer 处理则没有这个问题,因为 yield put 返回时,对应的 reducer 已经执行完成了。

这些其实都是 redux-saga 的注意事项,只不过在 dva 中 effects 的写法,generator function 都是作为 effect、通过 put action 触发的。实际上会有很多 generator function 并不直接处理 action,而是被其他 saga/generator function 调用。

我个人的做法是,还原到直接使用 redux-saga 时的写法,只有直接响应 action 的 generator function 才放到 dva effects 中,其他一律游离出来。

const model = {
  // ...

  effects: {
    * showItem({ payload }, { call }) {

      // 用:
      yield call(showItemFirstStageProcedure)
      yield call(showItemSecondStageProcedure)

      // 而不是:
      // yield put({ type: 'showItemFirstStage' })
      // yield take('showItemFirstStage/@<strong i="7">@end</strong>')
      // yield put({ type: 'showItemSecondStage' })
      // yield take('showItemSecondStage/@<strong i="8">@end</strong>')
      // ...after second stage
    },

    // ...
    // end effects
  },

  // ...
  // end model
}

游离的 generator function 中需要 saga 的 call/select/... 时,可以直接从 saga 中 import:

import { effects } from 'dva/saga'

const { call, select } = effects

但是 dva 为其 effects 中的方法提供的 puttake 经过一次封装(即 namespace 前缀处理),必须通过 effects methods 传递:
in https://github.com/dvajs/dva/blob/master/packages/dva-core/src/getSaga.js#L141

return { ...sagaEffects, put, take };

或者就写完整的 action type:

import { effects } from 'dva/saga'

const { take } = effects

// then
take(`${namespace}/${actionType}`)

put.resolve()是阻塞的

yield put.resolve({ type: 'addDelay', payload: { amount: 2 } });
const count = yield select(state => state.count);
yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } });

put.resolve()就是阻塞的,详情见redux-saga API

为什么要阻塞put,请问这里的应用场景是什么

如果 put 的 action 是被 saga (在 dva 中是 effect) 处理的,那么 yield put 返回时,对应的 saga/effect 还没有完成执行(redux-saga 的 scheduler 会将其入队,稍后再逐步调度),这样就不满足某些状态流程的阻塞要求。

如果我没有记错的话,put action 被 reducer 处理则没有这个问题,因为 yield put 返回时,对应的 reducer 已经执行完成了。

是的,我已经试过了yield put(reducers)是同步的 而yield put(effects)是异步的

为什么不能直接put ,非要yield put???

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

itiwll picture itiwll  ·  4评论

mclouvem picture mclouvem  ·  4评论

pengfeiWang picture pengfeiWang  ·  3评论

wm3445 picture wm3445  ·  3评论

yaeSakuras picture yaeSakuras  ·  3评论