我使用React和一些Redux完成了一个相当复杂的基于Web的编辑器。
有时在单击按钮或更改值时,我在Chrome中收到以下错误:
index.js:47804 Uncaught (in promise) RangeError: Maximum call stack size exceeded
at Store.fetchExisting (index.js:47804)
Promise.then (async)
dispatchStateChange @ index.js:46114
(anonymous) @ index.js:46129
(anonymous) @ index.js:43232
(anonymous) @ index.js:44816
schemeClicked @ index.js:49071
onClick @ index.js:49078
callCallback @ index.js:26503
invokeGuardedCallbackDev @ index.js:26541
invokeGuardedCallback @ index.js:26590
invokeGuardedCallbackAndCatchFirstError @ index.js:26604
executeDispatch @ index.js:26869
executeDispatchesInOrder @ index.js:26891
executeDispatchesAndRelease @ index.js:26989
executeDispatchesAndReleaseTopLevel @ index.js:27000
forEachAccumulated @ index.js:26970
runEventsInBatch @ index.js:27131
runExtractedEventsInBatch @ index.js:27140
handleTopLevel @ index.js:30604
batchedUpdates @ index.js:38940
batchedUpdates @ index.js:28342
dispatchEvent @ index.js:30685
interactiveUpdates @ index.js:38995
interactiveUpdates @ index.js:28361
dispatchInteractiveEvent @ index.js:30662
只有最后7个条目在我的代码中。以下其他条目均来自Chrome或React。在Firefox中,我无法获得类似的错误。可能是因为Firefox中的调用堆栈更大。
此行为的最明显原因将是无休止的递归。但是,该部分代码不包含任何此类递归,并且调用堆栈的深度也不是很大。
发生此错误的代码如下:
function dispatchStateChange(dispatch, update) {
update.then(s => dispatch(Object.assign({ type: ActionData.ActionId.CHANGE_STATE }, s)));
}
这里dispatch
是Redux调度,而update
是Redux存储的部分状态更新的承诺。我尝试调试它,但无法进入then
。
调用此代码的代码如下:
exports.Actions = {
initialize() {
return (dispatch, getState) => {
dispatchStateChange(dispatch, work({ initialize: true }, getState(), autoSave));
};
},
<other action creators>
};
这是我所有创建Redux实体的动作创建者的对象。
work
是一个很长的异步函数,它管理应用程序逻辑并进行大量派生值的计算。
Chrome调试器的范围窗口也没有显示太多。 dispatchStateChange
函数中的本地作用域仅包含3个条目。该闭包也仅包含14个条目。所以我在堆栈上甚至没有太多导致它溢出的变量。
有人知道这个问题可能是什么以及如何解决这个问题?可能是由于过多使用await
表达式而导致大量then
表达式引起的问题?