繁体   English   中英

在使用 Redux-Thunk 异步操作的 promise 链中使用 setInterval

[英]Using setInterval in promise chain which uses Redux-Thunk async action

我有一个相当模糊的问题,它可能确实是我自己的问题,如果是这样,请随时指出。

我有一个承诺链,我需要访问中间值以用于后续 API 调用。 一旦所有的承诺都得到解决,我就会执行一个使用各种中间返回值的 API 调用。

最后,根据该调用的结果,我最后调用 API。 但是,此调用的结果用于更新 Redux State,因此使用 Redux Thunk 作为中间件来促进异步操作。

挑战出现在我需要以设定的时间间隔轮询数据库以检查 Redux API 调用是否执行了它所请求的工作(这涉及在 ZE111446745A1825B8ZAE4 任务F87 上放置一些长时间运行的任务,然后在队列中放置一些长时间运行的任务工作完成后更新数据库)。

当数据库确认它确实已经更新完成任务状态时,我想清除 setIntervalId。 我已将代码简化为如下所示。 问题是执行不会等待 Redux 异步操作完成。 因此,它执行该操作,然后在 Redux 操作完成之前直接执行“if”检查。 因此 if 永远不会为真,并且轮询会无限期地继续。

我不知道如何确保 Redux 操作在代码继续之前完成。 我已经精简了代码以使逻辑到位,而不会用不相关的代码过度拥挤这篇文章。

有什么想法可以让我按预期工作吗?

buttonClickedHandler.js

callbackFn {function(){
    const a = ApiCallA(...) // Returns a promise

    const b = a.then(resA => {
        // Some work done here
        return ApiCallB(…); // Returns a promise

    const c = b.then(resB => {
        // Some work done here
        return ApiCallC(…); // Returns a promise  

    return Promise.all( ([a, b, c] )
        .then( ([resA, resB, resC] ) => {
            // Some work done here
            return ApiCallD
        })
        .then( resD => {
            const intId = setInterval( () => {
                reduxAsyncAction(resD.jobId) // <-- This makes a final API call
                    if (props.jobStatus){ // <-- jobStatus gets updated too late
                         clearInterval(intId ); 
                    }
                }, 5000)
          })
         .catch(err => console.log(err))
}

redux action creator

export const reduxAsyncAction= (jobId) => {
    return dispatch => {
        dispatch(taskStatusStart()); // <- Basic sync. action creator
        return databaseQuery() // Returns Promise therefore pushed to taskqueue while other function run
        .then(dbData=>{
            const completionStatus = dbData.status; // <- True or False
            dispatch(taskStatusSuccess(completionStatus)) // <- Basic sync. action creator
        },
        error => {
            dispatch(taskStatusFail(error)); // <- Basic sync. action creator
        })
    };
}


使用componentDidUpdateuseEffect

  1. 这些将在您的 redux 商店中的props.jobStatus更新时运行
  2. 检查您从reduxAsyncAction调度的taskStatusSuccess(completionStatus)taskStatusFail(error)
  3. clearinterval(intId)如果状态匹配

您还需要通过在callbackFn之外声明,将 intId 添加到intId中,例如:

  • 基于this.intId的组件的构造函数中的 this.intId

  • let intId在功能组件的顶部。

基于 Class 的组件:

componentDidUpdate(){
    if (intId && props.jobStatus === 'completionStatus' || props.jobStatus === 'error'){
          clearInterval(intId); 
          intId = null;
    } 
}

功能组件:

useEffect(()=>{
    if (intId && props.jobStatus === 'completionStatus' || props.jobStatus === 'error'){
        clearInterval(intId); 
        intId = null;
    } 
},[props.jobStatus])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM