首页 文章

在redux状态下放置返回promise的函数

提问于
浏览
3

我会解释为什么我想稍后这样做 . 这是问题所在 . 我有一个返回如下承诺的函数:

const testFunc = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (Math.random() >  0.5) {
        resolve('succeeded');
      } else {
        reject('failed');
      }
    }, 1000);
  });
};

正如所料,我可以像这样调用它:

testFunc()
  .then((result) => console.log(result)) // 'succeeded'
  .catch((error) => console.log(error)); // 'failed'

或者将其分配给变量并像这样调用它

const testFuncVar = testFunc;
testFuncVar()
  .then((result) => console.log(result)) // 'succeeded'
  .catch((error) => console.log(error)); // 'failed'

这些都是预期的 . 但是,一旦我将函数置于redux状态,然后从那里调用它,它就不再起作用了 . 这是我做的(粗略简化) .

const initialState = {testFunc: testFunc};
// redux reducer, action creator, etc.
...
...
// somewhere later. Here I'm using redux-thunk to access redux state
function testFunInState() {
  return (dispatch, getState) => {
    const {testFunc} = getState();
    // this is not working
    testFunc()
      .then((result) => console.log(result))
      .catch((error) => console.log(error));
  };
}

我得到的错误是 _promise2 is not defined . 请注意,变量名称 _promise2 应该来自babel transpiler . 如果我 console.log(state.testFunc)console.log(testFunc) ,我得到:

testFunc() {
  return new _promise2.default(function (resolve, reject) {
    if (Math.random() > 0.5) {
      resolve('succeeded');
    } else {
      reject('failed');
    }
  });
}

所以只要函数处于redux状态, Promise 对象就会丢失?

但我确实找到了解决方法 . 如果我将功能更改为

const testFunc = (resolve, reject) => {
  setTimeout(() => {
    if (Math.random() >  0.5) {
      resolve('succeeded');
    } else {
      reject('failed');
    }
  }, 1000);
};

并以 resolvereject 作为参数传入它,然后我很好 .

// this works
new Promise((resolve, reject) => state.testFunc(resolve, reject))
  .then((result) => console.log(result))
  .catch((error) => console.log(error));

我想知道为什么返回promise的函数一旦放入redux存储就不起作用,但是没有返回promise的函数有效?

现在问我为什么要这样做 . 我想要实现的是拥有一个定期调度一些异步操作的作业队列,并根据结果(解决或拒绝)执行其他操作(如重试或发送通知) . 我想在队列中动态添加/删除作业,因此很难有一个可以处理所有可能操作的reducer . 感觉这是接近它的合理方式 . 我愿意接受建议 .

2 回答

  • 2

    通过更多的挖掘,我终于认为问题确实与redux或promise无关 . 这只是因为它们通过赋值给 initialState object literal而被添加到redux状态 . 当它以这种方式完成时,绑定将丢失,因此 _promise2 is undefined 错误 . 实际上如果我动态地将 testFunc 添加到redux状态(例如通过动作创建器和减速器),绑定得到保留,一切正常 . 以下是问题https://stackoverflow.com/a/2702028/4401488的更详细说明 .

    仅供参考,以下是通过reducer将 testFunc 添加到redux状态的代码

    const initialState = {};
    // redux reducer
    export default function jobReducer(state = initialState, action = {}) {
      switch (action.type) {
        case ADD_JOB:
          return {job: action.job};
        default:
          return state;
      }
    }
    
    // action creator
    export function addJob(job) {
      return {
        type: ADD_JOB,
        job: job
      };
    }
    ...
    // add testFunc to redux state via action creator,
    // I'm using redux-thunk here to access dispatch
    function addTestFun() {
      return (dispatch) => {
        dispatch(addJob(testFunc));
      };
    }
    ...
    // invocation of testFunc. Here I'm using redux-thunk to access redux state
    function testFunInState() {
      return (dispatch, getState) => {
        const {testFunc} = getState();
        // Now this is working
        testFunc()
          .then((result) => console.log(result))
          .catch((error) => console.log(error));
      };
    }
    
  • 1

    您需要使用Redux的中间件,例如Redux Thunk

    import { createStore, applyMiddleware } from 'redux';
    import thunk from 'redux-thunk';
    import rootReducer from './reducers/index';
    
    // Note: this API requires redux@>=3.1.0
    const store = createStore(
      rootReducer,
      applyMiddleware(thunk)
    );
    

    然后像这样编写你的动作:

    const INCREMENT_COUNTER = 'INCREMENT_COUNTER';
    
    function increment() {
      return {
        type: INCREMENT_COUNTER
      };
    }
    
    function incrementAsync() {
      return dispatch => {
        setTimeout(() => {
          // Yay! Can invoke sync or async actions with `dispatch`
          dispatch(increment());
        }, 1000);
      };
    }
    

    您也可以尝试使用Redux-Promise

相关问题