关于 dva put,put.resolve

​ 由于项目使用的是 dva.js ,在项目重遇到一个场景是需要拿着特定的选中单据的 taskId 去获取单据真正的 id ,其中获取真正 id 的接口是需要轮询3次的,下面是项目中的一部分代码。

​ 其中业务场景是这样的,在一个单据 table 选择页面,选择部分单据,然后点击创建出货资料按钮,调用接口 detailLines 去获取到一个 taskId ,然后再带着这个 taskId 去轮询(轮询三次)获取单据的唯一 id ,获取成功之后才跳去到步骤条的第一步,否则返回首页

import { message } from 'antd';
import * as service from '@/service/createASN';
import { translateFormData } from '@/utils/fn';
export default {
    namespace: 'order',
    state: { },
    reducers: {
        updateState(state, { payload }) {
            return {
                ...state,
                ...payload,
    effects: {
         // 轮询接口
         *createTasks({ payload: { id } }, { put, call }) {
            console.log('id');
            let { data } = yield call(service.createTasks, id);
            if (!data.success) {
                // 等待5秒
                yield new Promise((resolve) => setTimeout(resolve, 5000));
                let response = yield call(service.createTasks, id);
                if (!response.data.success) {
                    // 等待5秒
                    yield new Promise((resolve) => setTimeout(resolve, 5000));
                    response = yield call(service.createTasks, id);
                    if (!response.data.success) {
                        message.error(response.data.failedReason);
                data = response.data;
                console.log(1111);
                yield put({ type: 'updateState', payload: { id: data.id, success: data.success } });
                console.log(33333);
        *detailLines({ payload }, { put, call, select }) {
            console.log('start');
            const { data: taskId } = yield call(service.detailLines, payload);
            console.log('end', taskId);
            yield put.resolve({ type: 'createTasks', payload: { id: taskId } });
            console.log('getid');
            const { id, success } = yield select(({ createASNSelectOrder }) => createASNSelectOrder);
            console.log('getid--->跳转');
            if (!id || !success) {
                yield put(routerRedux.goBack());
                return false;
            console.log('go');
            yield put({ type: 'goTo', payload: { id, OrderType: 'PO' } });
        // 创建成功 跳转
        *goTo({ payload }, { put }) {
            console.log('好的---我跳转了');
            const { id, OrderType } = payload;
            yield put(routerRedux.push(`/app/detail/${OrderType}/${id}`));

打印结果如下:
在这里插入图片描述
​ 其中用到了yield put()yield put.resolve(),为了方便大家理解他们是否是阻塞的,下面用几个简单的例子来说明

案例代码如下:

// xxx.jsx
textBtn = () => {
    const { dispatch } = this.props;
    dispatch({
        type: 'asn/textbtn',
        payload: {},
    });
aynctextBtn = () => {
    const { dispatch } = this.props;
    dispatch({
        type: 'asn/asynctextbtn',
        payload: {},
    });
<Button onClick={this.textBtn} type="primary">测试按钮</Button>
<Button onClick={this.aynctextBtn} type="primary">异步测试按钮</Button>
// xxx.js
reducers: {
        initData(state, { payload }) {
            for (let i = 1; i < 10; i++) {
                console.log(i);
            return {
                ...state,
                ...payload,
 effects: {
     	//异步获取数据
        *asyncinitData({ payload }, { put, call }) {
            yield put({
                type: 'initData',
            });
		// 点击按钮
        *textbtn({ payload }, { put, call }) {
            console.log('开始测试');
            yield put.resolve({
                type: 'initData',
                payload: '我是一个测试语句',
            });
            console.log('测试结束');
        // 异步------点击按钮
        *asynctextbtn({ payload }, { put, call }) {
            console.log('开始测试');
            // yield put.resolve({   -------> 异步变同步,非组赛变阻塞
            yield put({
                type: 'asyncinitData',
                payload: '我是一个测试语句',
            });
            // yield take('asyncinitData/@@end');  -------> 监听asyncinitData,等待asyncinitData执行完成在执行下面代码,非组赛变阻塞
            console.log('测试结束');
  1. 当点击测试按钮时候,控制台打印结果
    在这里插入图片描述
  2. 当点击异步测试按钮时候,控制台打印结果
    在这里插入图片描述
  3. 当点击异步测试按钮时候,但是把yield put改成yield put.resolve,控制台打印结果
    在这里插入图片描述
  4. 当点击异步测试按钮时候,加上代码yield take('asyncinitData/@@end');,控制台打印结果
    在这里插入图片描述
  • yield put直接调用reducer,是堵塞的,同步,
  • 调用非reducer函数,是非堵塞的,异步
  • 使用put.resolve ,堵塞的,同步
  • 使用yield take('asyncinitData/@@end')去监听asyncinitData执行
关于dva的put,put.resolve​ 由于项目使用的是dva.js,在项目重遇到一个场景是需要拿着特定的选中单据的taskId去获取单据真正的id,其中获取真正id的接口是需要轮询3次的,下面是项目中的一部分代码。​ 其中业务场景是这样的,在一个单据table选择页面,选择部分单据,然后点击创建出货资料按钮,调用接口createASNviaPoLines去获取到一个taskId,然后再带着这个taskId去轮询(轮询三次)获取单据的唯一id,获取成功之后才跳去到步骤条的第一步,否则返回首页 state:是定义的一些数据 subscriptions:默认在哪个页面请求 effect:里面有个 *fetch 里面有两个参数,分别是payload(传递的数据),第二个参数里面有三个值分别是call、put、select。call是返回一个箭头函数,通常是用来请求。put就是等call执行完毕后,然后执行一个函数,里面可以进行设置咱们想要设置的一些数组,数据,类型就是reducers里面定义的一些方法
这年头,Redux 状态管理框架满天飞,前几天在网上闲逛偶然又发现 Rematch、Mirror、Smox、Xredux,都用了一下,发现都是套瓷娃娃,大同小异,拿几个比较历害的来说: DvaJS Github Stars 12000+ Rematch Github Stars 5000+ Mirror Github Stars 1200+ 无非就是类似这样的: model({ sta...
dva model 中使用yield put 执行effects中另一个方法,发起请求,不会等这个请求执行完才执行下面的方法。 effects: { *effectAll({ payload }, { put, call }) { console.log('effectAll-start') yield put({ type.
dva中effect内调用另一个effect的,实现put阻塞式调用的方法 在项目中通常会有在一个effect中调用另一个effect的需求,实现方法就是直接使用put *a({ payload}, {put, call,take}) { try { console.log(a) yield put({type: 'b',payload: {}}...
如果yield call的是一个Promise对象,那只有在Promise返回的是resolve方法的情况下,下面跟着的yield put及后面的代码才会执行,若返回了rejector则后面的代码则全部停止执行。 // models/mdeical.ts文件: * fetchMedicalLast({ payload }, { call, put }) { const { medicalIndexList } = yield call(api.medical.fetchMedicalLas
解决Please use require(“history“).createHashHistory instead of require(“history/createHashHistory“) 程序猿199108: 大哥,依赖每次会重新下载覆盖的啊