Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React-Redux应用程序-复杂初始化操作组合在其他操作完成之前执行最终承诺_Javascript_Reactjs_Middleware_Redux_Thunk - Fatal编程技术网

Javascript React-Redux应用程序-复杂初始化操作组合在其他操作完成之前执行最终承诺

Javascript React-Redux应用程序-复杂初始化操作组合在其他操作完成之前执行最终承诺,javascript,reactjs,middleware,redux,thunk,Javascript,Reactjs,Middleware,Redux,Thunk,我正在开发一款需要管理大量数据的应用程序。 在init进程中,当用户看到加载条时,必须执行几个api调用 以下是我的初始操作: export function init(key) { return (dispatch, getState) => { // start init dispatch(initStart()); setTimeout(() => { dispatch(initProcess(10)); }, 0)

我正在开发一款需要管理大量数据的应用程序。 在init进程中,当用户看到加载条时,必须执行几个api调用

以下是我的初始操作:

export function init(key) {

  return (dispatch, getState) => {

    // start init
    dispatch(initStart());

    setTimeout(() => {
      dispatch(initProcess(10));
    }, 0)


    return Promise.all([

      // load users
      dispatch(loadUsers(key)).then(() => {
        dispatch(initProcess(30));
      }),

      // load other stuff
      // ...

      // load articles
      dispatch(loadArticles(key)).then(() => {
        dispatch(initProcess(60));
      }),

    // should be executed after all actions/reducers are done
    ]).then(() => {
      setTimeout(() => {
        dispatch(initFinish());
      }, 700);
    });
  }
}
到目前为止,它工作得很好,但将有2万到5万篇文章。后端必须执行一些连接才能将数据收集到一起,因此如果我尝试将它们整合在一起,我肯定会得到服务器超时

我们的想法是先获取总数,然后在一个循环中获取1k个片段中的文章。但它不会按我需要的方式工作。我将在物品清点后,而不是在取回物品后,发送
initFinish

以下是
loadArticles
操作:

export function loadArticles(key) {
  return (dispatch, getState) => {

    // check local db first

    // get total number
    return dispatch(countArticles(key))
    .then(result => {
      Promise.all([
        // No idea how to put the loop in here :(
        dispatch(fetchArticles(key, 1000)),
      ])
    });
 }
}

我还没有循环,但这不是重点。逻辑是一样的。在
fetchArticles
完成之前,我返回
dispatch(countArticles(key))

有人有什么暗示吗?那太棒了


编辑

coutArticles
fetchArticles

function countArticles(key) {
  return {
    [CALL_API]: {
      types: [ COUNT_ARTICLES_REQUEST, COUNT_ARTICLES_SUCCESS, COUNT_ARTICLES_FAILURE ],
      endpoint: `articles`,
      schema: Schemas.ARTICLE_COUNTER
    }
  }
}
function fetchArticles(key, take, skip) {
  return {
    [CALL_API]: {
      types: [ FETCH_ARTICLES_REQUEST, FETCH_ARTICLES_SUCCESS, FETCH_ARTICLES_FAILURE ],
      endpoint: `articles/${take}/${skip}`,
      schema: Schemas.ARTICLE_ARRAY
    }
  }
}
中间件是相同的


2。编辑

如果我改变

// get total number
return dispatch(countArticles(key))
.then(result => {
  Promise.all([
    // No idea how to put the loop in here :(
    dispatch(fetchArticles(key, 1000)),
  ])
});

我得到
uncaughttypeerror:无法读取
dispatch(loadArticles(key))
上未定义的属性“then”


3。编辑

几天后,我还在战斗^^

以下是简化的init函数,它应该(仅)获取计数结果,然后获取文章:

但现在我已经失败了:

export function init(key) {

  return (dispatch, getState) => {

    countArticles(key).then(result => {
      console.log(result);
    });

  }
}
输出:

Uncaught TypeError: countArticles(...).then is not a function

我在链接调度方面也有问题;它应该返回一个
承诺
,但我无法让它工作

所以我会这样改变逻辑

countArticles(key).then(result => {
    dispatch( {
        type:  RECEIVED_NUM_ARTICLES,
        value: result
    })
    Promise.all([...Array(Math.floor(result/1000))].map(_ => 
         fetchArticles(key,1000).then(res => dispatch( {
            type:  RECEIVED_1000_ARTICLES,
            value: res
         })
    )).then( _ => dispatch({
            type:  RECEIVED_EVERYTHING
            value: 'whatever'
         })
    )
)
(我没有测试此代码)

但是基本上:
fetch
然后
dispatch
结果,然后链接另一个fetch/dispatch序列,等等

循环需要返工才能获取模


这种方法的优点是,当你有文章时,你可以用文章的数量来更新UI,然后每1000篇文章就更新一次,最后在完成时发出通知

尝试将
返回
移动到
调度
调用内
承诺。如果我错了,所有的
都会纠正我,但是
承诺。所有
都接受一个数组<代码>返回
作为数组值将是语法错误?!是的,你说得对。我一路都没想过:PMaybe try
return Promise.all()
相反?已经尝试过,也不起作用。我知道,你说过它没有经过测试,但应该是类似于
return dispatch(countArticles(key))。然后因为我得到了一个错误
countArticles(…)。然后不是一个函数
哦,我想你关注的是循环,但这不是我的主要问题。事实上,目前这根本不是问题。我在调度操作的顺序上遇到了问题。
countArticles
是否在Ajax调用后返回了一个
Promise
?无论如何,las的注释是:fetch->dispatch->fetch->dispatch;不要连锁发送,连锁提取您不应该尝试返回
countArticles
dispatch。它会导致与
fetchArticles()
的竞争条件。但是,您需要将其包装在
分派
函数中,因为中间件返回一个
承诺
。使用上面的代码,只需将其修改为
dispatch(countArticles(key))。然后(…)
,它就可以工作了。
countArticles(key).then(result => {
    dispatch( {
        type:  RECEIVED_NUM_ARTICLES,
        value: result
    })
    Promise.all([...Array(Math.floor(result/1000))].map(_ => 
         fetchArticles(key,1000).then(res => dispatch( {
            type:  RECEIVED_1000_ARTICLES,
            value: res
         })
    )).then( _ => dispatch({
            type:  RECEIVED_EVERYTHING
            value: 'whatever'
         })
    )
)