如何解决Redux中的递归函数
尝试传递对递归函数的引用以检查Redux操作数据获取是否已完成,但出现函数引用错误
const fetchAccountComplete = (state,accountNo) => { //state here is function reference
return new Promise(resolve => {
(function waitForFetchComplete(state,accountNo) {
const {isFetching,receivedAt} = state().account[accountNo] // getting state not a function here
if (!isFetching) return resolve()
setTimeout(waitForFetchComplete,100)
})()
})
}
在Redux分派操作中是否有更好的方法可以将诺言返回给调用方函数,因此一旦提取数据,我就需要在其他操作中执行其他一些逻辑。
更新1:
应该更清楚了。此请求有两个调用方,即说帐户数据的操作。您将第一个调用者定向到类似于上面的注释,因此请等到完成为止,第二个调用者将不会再次执行异步调用,并且需要检查数据提取是否完成,因此请尝试查看具有检查状态的递归函数,以便使promise可以被解决了
解决方法
您可以利用有前途的链接。 示例:
具有三个动作,例如:IS_FETCHING,FETCH_SUCCESS,FETCH_ERROR。
IS_FETCHING: 只需将您的状态设置为待处理(例如,对于显示加载动画可能会有用)。
FETCH_SUCCESS: 将包含获取结果以更新状态。还将清除isUpdating标志
FETCH_ERROR: 将包含由于提取而引起的任何可能的错误(应用程序或网络错误)。还将清除isUpdating标志
然后,您可以在应用程序级别执行以下操作:
dispatch({type: IS_FETCHING,payload: data});
fetch(`https://MY-SERVER.com/?data=${data}`)
.then(response => response.json())
.then(json =>
dispatch({
type: isError(json) ? FETCH_RESULT : FETCH_ERROR,payload: json
})
);
您甚至可以从动作创建者那里受益。 这是一个很好的指南:https://redux.js.org/advanced/async-actions
,如果您有一个函数返回带有相同参数的多次调用的promise,则可以将其分组,以便当该函数仍具有未解决的promise并尝试再次调用它时不调用该函数具有相同的参数。
这里是一个例子:
//group promise returning function
const createGroup = (cache) => (
fn,getKey = (...x) => JSON.stringify(x)
) => (...args) => {
const key = getKey(args);
let result = cache.get(key);
if (result) {
return result;
}
//no cache
result = Promise.resolve(fn.apply(null,args)).then(
(r) => {
cache.done(key); //tell cache promise is done
return r;
},(e) => {
cache.done(key); //tell cache promise is done
return Promise.reject(e);
}
);
cache.set(key,result);
return result;
};
//creates a cache that will remove cached value when
// Promise is done (resolved or rejected)
const createCache = (cache = new Map()) => {
return {
get: (key) => cache.get(key),set: (key,value) => cache.set(key,value),done: (key) => cache.delete(key),};
};
//function that retuns a promise
const later = (time,value) => {
console.log('executing later with values',time,value);
return new Promise((r) =>
setTimeout(() => r(value),time)
);
};
//create group function with a cache that will remove
// cache key when promise is resolved or rejected
const groupAndRemoveCacheOnDone = createGroup(
createCache()
);
//grouped version of the later function
const groupedLater = groupAndRemoveCacheOnDone(later);
//testing the groped later
groupedLater(100,8); //first call causes console.log
groupedLater(100,8); //same arguments will not call later
groupedLater(100,8); //will not call later
//will call later because arguments are not the same
// as the other calls
groupedLater(100,'XX');
groupedLater(100,8) //will not call later
.then((value) => {
console.log('resolved with:',value);
//this will call later because cache value is removed
// after promise is resolved
return groupedLater(100,8);
})
.then(() => {
//testing with fetchAccountComplete
console.log(
'***** how many times is fetchAccountComplete called *****'
);
const fetchAccountComplete = (state,accountNo) => {
console.log(
'fetchAccountComplete called with',accountNo
);
return new Promise((resolve) => {
(function waitForFetchComplete(state,accountNo) {
const {
isFetching,receivedAt,} = state().account[accountNo]; // getting state not a function here
if (!isFetching) return resolve();
setTimeout(
() => waitForFetchComplete(state,accountNo),100
);
})(state,accountNo);
});
};
const data = {
account: [{ isFetching: true }],};
const state = () => data;
const groupedFetchAccountComplete = groupAndRemoveCacheOnDone(
fetchAccountComplete
);
groupedFetchAccountComplete(state,0);
groupedFetchAccountComplete(state,0).then((resolve) =>
console.log('resolved')
);
data.account[0].isFetching = false;
});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。