【发布时间】:2022-01-19 17:38:39
【问题描述】:
我正在尝试 debounce() 和 Observable 与 pipe() 并链接 .subscribe() 但由于某种原因,订阅中的函数仍一次被调用了十几次。
我要做的是通过管道传递withChangesForTables 并消除同步调用,因为我希望仅在进行了整批更改时才调用它。所以我为同步创建了一个提供程序并将它包裹在我的 RootNavigator 上
withChangesForTables on WatermelonDB source code
const SyncContext = createContext();
function useSync() {
return useContext(SyncContext);
}
function SyncProvider({children}) {
const [isSyncing, setIsSyncing] = useState(false);
const [hasUnsynced, setHasUnsynced] = useState(false);
async function checkUnsyncedChanges() {
const hasChanges = await hasUnsyncedChanges({
database
});
setHasUnsynced(hasChanges);
}
async function sync() {
await checkUnsyncedChanges();
if (!isSyncing && hasUnsynced) {
setIsSyncing(true);
await synchronizeWithServer();
setIsSyncing(false);
}
}
database.withChangesForTables([
'table_name',
'table_name2'
]).pipe(
skip(1),
// ignore records simply becoming `synced`
filter(changes => !changes.every(change => change.record.syncStatus === 'synced')),
// debounce to avoid syncing in the middle of related actions - I put 100000 to test only
debounceTime(100000),
).subscribe({
//calls API endpoint to sync local DB with server
next: () => sync(),
error: e => console.log(e)
});
const value = {
isSyncing,
hasUnsynced,
checkUnsyncedChanges,
sync
};
return (
<SyncContext.Provider value={value}>
{children}
</SyncContext.Provider>
);
}
【问题讨论】:
-
您是否多次订阅?
-
@ggradnig 抱歉,如果这是一个愚蠢的问题,因为我对 rxjs 很陌生,但我怎么知道我是否订阅了多次?我基本上在我创建的提供程序中有此代码。然后将提供程序包裹在 RootNavigator
-
所以问题是你多久执行一次你发布的代码。例如,将
console.log语句添加到您的代码中,然后查看它的记录频率。应该只有一次! -
@ggradnig 因此,每次本地数据库发生更改时都会执行代码,所以我实际上需要它多次运行,但我只是不希望它以 100x/秒的速度运行。我只希望它最多每秒运行一次
-
我假设您的组件被多次渲染。还有怎么退订?尝试在
skip(1)之后添加类似take(1)的内容;
标签: javascript react-native rxjs observable watermelondb