关于dva的put,put.resolve

关于dvaput,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执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值