【问题标题】:`.pipe()` not executing `debounceTime``.pipe()` 没有执行 `debounceTime`
【发布时间】:2022-01-19 17:38:39
【问题描述】:

我正在尝试 debounce()Observablepipe() 并链接 .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


【解决方案1】:

我不得不将withChangesForTables 移动到useEffect 并重新运行它才能取消订阅,这似乎已经解决了问题。代码现在看起来像这样:

useEffect(() => {
    return database.withChangesForTables([
        'table_name',
        'table_name2'
    ]).pipe(
        skip(1),
        filter(changes => !changes.every(change => change.record.syncStatus === 'synced')),
        debounceTime(500),
    ).subscribe({
        next: () => sync(), 
        error: e => console.log(e)
    });
}, [])

【讨论】:

    猜你喜欢
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 2020-05-15
    • 2021-01-05
    • 1970-01-01
    • 2016-05-08
    • 2021-08-26
    相关资源
    最近更新 更多