Javascript React-Redux应用程序-复杂初始化操作组合在其他操作完成之前执行最终承诺
我正在开发一款需要管理大量数据的应用程序。 在init进程中,当用户看到加载条时,必须执行几个api调用 以下是我的初始操作: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)
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 tryreturn 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'
})
)
)