javascript - 将返回 promise 的函数置于 redux 状态

标签 javascript reactjs redux es6-promise react-redux

稍后我会解释为什么要这样做。 这就是问题所在。我有一个返回如下 promise 的函数:

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 store 就不能工作,但是一个不返回 promise 的函数可以工作?

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

最佳答案

经过进一步挖掘,我终于发现问题确实与 redux 或 promise 无关。这仅仅是因为他们通过分配给 initialState 对象字面量来将 testFunc 添加到 redux 状态。以这种方式完成后,绑定(bind)将丢失,因此出现 _promise2 is undefined 错误。实际上,如果我动态地将 testFunc 添加到 redux state(例如,通过 action creator 和 reducer),绑定(bind)将得到保留并且一切正常。这是问题的更详细解释 https://stackoverflow.com/a/2702028/4401488 .

仅供引用,这里是通过reducer将testFunc添加到redux state的代码

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));
  };
}

关于javascript - 将返回 promise 的函数置于 redux 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38154202/

相关文章:

javascript - 选中复选框后无法设置行的类

javascript - ReactJs - 每个子组件的 onclick 事件

javascript - React native JAVA_HOME 设置为无效目录

函数组件内的 ReactJS 生命周期方法

javascript - 更新 redux 商店上的 isLoading 字段

javascript - 如何使用音频元素创建连续的曲调

javascript - Breeze 无法使用在 Breeze 1.4.14 中具有 .expand 子句的查询返回扩展实体

javascript - .setHours 返回错误的时间

javascript - 如何映射列表并在其中实现异步?

laravel - React JS Fetch 返回空响应,但 Postman 不返回