react redux - 应用 "fetch" 并在调度内部调度失败

react redux - applying a "fetch" and dispatch inside of a dispatch fails

我有一个工作操作可以通过简单的调用 "saveJwt(data)".

保存 JWT 令牌

动作如下:

export const requestLoginToken = (username, password) =>
  (dispatch, getState) => {
    dispatch({type: REQUEST_LOGIN_TOKEN, payload: username})

    const payload = {
      userName: username,
      password: password,
    }

    const task = fetch('/api/jwt', {
      method: 'POST',
      body: JSON.stringify(payload),
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      },
    })
      .then(handleErrors)
      .then(response => response.json())
      .then(data => {
        dispatch({type: RECEIVE_LOGIN_TOKEN, payload: data})
        saveJwt(data)
      })
      .catch(error => {
        clearJwt()
        dispatch({type: ERROR_LOGIN_TOKEN, payload: error.message})
      })
    addTask(task)
    return task
  }

然后我在"saveJwt(data)"下面加入了这段代码:

    if (!confirmSelectDataExistance()) {
      dispatch({ type: REQUEST_SELECT_DATA })
      const token = getJwt()
      const headers = new Headers({
        'Authorization': `Bearer ${token}`
      })
      const retrieveSelectData = fetch('/api/SelectData/SelectData', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json;charset=UTF-8'
        },
      })
        .then(handleErrors)
        .then(response => response.json())
        .then(selectData => {
          dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
          saveSelectData(selectData)
        })
   }

所有它应该做的就是检查项目是否在本地存储中,如果是,这次在添加 JWT 的情况下再次获取。

这是完成的操作,因此您可以看到它所在的位置:

export const requestLoginToken = (username, password) =>
  (dispatch, getState) => {
    dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })

    const payload = {
      userName: username,
      password: password,
    }

    const task = fetch('/api/jwt', {
      method: 'POST',
      body: JSON.stringify(payload),
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      },
    })
      .then(handleErrors)
      .then(response => response.json())
      .then(data => {
        dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
        saveJwt(data)
        //selectData download if nothing is local storage.
        if (!confirmSelectDataExistance()) {
          dispatch({ type: REQUEST_SELECT_DATA })
          const token = getJwt()
          const headers = new Headers({
            'Authorization': `Bearer ${token}`
          })
          const retrieveSelectData = fetch('/api/SelectData/SelectData', {
            method: 'GET',
            headers: {
              'Content-Type': 'application/json;charset=UTF-8'
            },
          })
            .then(handleErrors)
            .then(response => response.json())
            .then(selectData => {
              dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
              saveSelectData(selectData)
            })
        }
      })
      .catch(error => {
        clearJwt()
        dispatch({ type: ERROR_LOGIN_TOKEN, payload: error.message })
      })
    addTask(task)
    return task
  }

所以现在我的第一次获取以未定义的承诺结束,它只是跳到底部,任务的值为未定义,

你会相信昨天它运行完美,而当我今天尝试它时却失败了。

为什么那个代码块导致整个事情失败..我把它注释掉并且它工作正常..

我怀疑它与两个承诺等有关,但必须有一种正确的方法来管理它。我本以为如果它要保存 JWT 令牌,那将表明它已完成第一次下载但是其他地方出了问题...在那段代码中或者更可能是它的使用方式。

假设 confirmSelectDataExistance 是异步的并且 returns 承诺并且承诺 retrieveSelectData 必须在 requestLoginToken 之前解决,解决方案可能是:

export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
   dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })

   const payload = {
     userName: username,
     password: password,
   }

const task = fetch('/api/jwt', {
  method: 'POST',
  body: JSON.stringify(payload),
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  },
})
  .then(handleErrors)
  .then(response => response.json())
  .then(data => {
    dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
    saveJwt(data)
    //selectData download if nothing is local storage.

    return confirmSelectDataExistance().then(isConfirmed => {
      if (!isConfirmed) {
        dispatch({ type: REQUEST_SELECT_DATA })
        const token = getJwt()
        const headers = new Headers({
          'Authorization': `Bearer ${token}`
        })
        const retrieveSelectData = fetch('/api/SelectData/SelectData', {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json;charset=UTF-8'
          },
        })
        .then(handleErrors)
        .then(response => response.json())
        .then(selectData => {
          dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
          saveSelectData(selectData)
        });

        return retrieveSelectData;
      }
    })
  })
  .catch(error => {
    clearJwt()
    dispatch({ type: ERROR_LOGIN_TOKEN, payload: error.message })
  })
addTask(task)
return task
}

如果 saveSelectData 也是异步的,您应该改为调用

 return saveSelectData(selectData);