美文网首页JavaScriptReactJS
dva中effects核心模拟实现

dva中effects核心模拟实现

作者: 凌风x | 来源:发表于2018-11-19 15:11 被阅读3次

    最近师兄搞了一下蚂蚁金服的 ant-design提供的后台模板框架(基于react)由于这个模板使用的是dva框架,里面各种ES6/ES7的新思想,于是小研究了一下effects。主要是模拟effetcs的异步机制。

    ant官方栗子:

    export default {
      namespace: 'puzzlecards',
      state: {
        data: [],
        counter: 0,
          },
    //+++++++++++++++++++++++++++主要实现一下功能+++++++++++++++++++++++++++++++++++++++++
      effects: {
        *queryInitCards(_, sagaEffects) {
          const { call, put } = sagaEffects;
          const endPointURI = 'https://08ad1pao69.execute-api.us-east-1.amazonaws.com/dev/random_joke';
    
          const puzzle = yield call(request, endPointURI);
          yield put({ type: 'addNewCard', payload: puzzle });
    
          yield call(delay, 3000);
    
          const puzzle2 = yield call(request, endPointURI);
          yield put({ type: 'addNewCard', payload: puzzle2 });
        }
      },
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      reducers: {
        addNewCard(state, { payload: newCard }) {
          const nextCounter = state.counter + 1;
          const newCardWithId = { ...newCard, id: nextCounter };
          const nextData = state.data.concat(newCardWithId);
          return {
            data: nextData,
            counter: nextCounter,
          };
        }
      },
    };
    

    师兄实现的核心代码

                    let url = "http://xxxx";
                    let param = { name: "xx", age: 22 };
    
                    console.log("before fetch<<<<<<<<<<<<<<<");
    
    
                    let generatorOutter = {
                            effects: {
                                    * httpGet(_, sagaEffects) {
                                            const { _call, _put } = sagaEffects;
                                            let _param = { url: url, param: param }
                                            let res = yield _call(_httpGet, _param);
                                            console.log(res, "1",processId);
                                            yield _put(callback, res,processId);
                                            console.log(res, "2",processId);
                                            yield _call((param)=>{
                                                    console.log("this is not a Promise fnc",processId);
                                                    console.log("normal fnc param:",param,processId);
                                            },{ppip:processId})
                                    },
                            }
                    }
                    //数据回调方法
                    function callback(resData) {
                            console.log(">>>>>>>>>回调获取的数据<<<<<",processId);
                            console.log(resData,processId);
                    }
                    //主入口
                    let main = function () {
                            let generator = generatorOutter.effects;
                            for (let fnc in generator) {
                                    let _step = generator[fnc](_, sagaEffects);
                                    sagaEffects.setStep(_step);
                                    _step.next();
                            }
                    }
    
                    let sagaEffects = {
                            step: new Object(),
                            setStep: function (_step) {
                                    this.step = _step;
                            },
                            /*getStep: function () {
                                    return this.step;
                            },*/
                            _call:  function (fnc, param) {
                                    let step = sagaEffects.step;
                                    if (sagaEffects._chargePromise(fnc)) {
                                            console.log("传入Promise",processId);
                                            fnc(param).then(res => {
                                                    if (step) step.next(res);
                                            })
                                    } else {
                                             sagaEffects._async_call(fnc, param).then((res)=>{
                                                            if (step) step.next(res);
                                            });   
                                    }
                            },
                            _put: function (callback, param) {
                                    sagaEffects._async_call(callback, param).then((res)=>{
                                            sagaEffects.step.next(res);  
                                    }); 
                            },
                            _async_call:async function(fnc, param){
                                    return await  fnc(param);
                            }, 
                            _chargePromise(fnc) {
                                    if (fnc !== null && ( typeof fnc === 'function') &&typeof fnc.then === 'function') 
                                    return true;
                                    return false;
                            },
                            _closeGenerator(){}
                    }
                    
                    async function _httpGet({url, param}) {
                            url = handlerParams(url, param);
                            try {
                                    const response = await fetch(url, { credentials: 'include', method: 'GET' });
                                    return await response.json();
                            } catch (e) {
                                    console.log(e);
                            }
                    }
    
                    //开始测试
                    main();
    

    看下效果,我同时调用了6次分别传入不同的id以区别,id顺序不是1-6说明异步有效

    image.png

    看下网络请求,同时发起

    image.png

    End

    这里我主要实现了sagaEffects中的call和put方法,也就是传入的方法的执行和返回数据,ES6的异步还是很有意思的,代码简洁了不少。
    2018-11-19

    相关文章

      网友评论

        本文标题:dva中effects核心模拟实现

        本文链接:https://www.haomeiwen.com/subject/slxafqtx.html