From 6ca6310f759bd459b66d5f4eb93cb91202022316 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 16 Oct 2024 06:30:22 +0000 Subject: [PATCH] refactor: use debounce and counter to avoid race conditions --- .../smartsheet/column/FormulaOptions.vue | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue index 2d24572b3d..39956bb80a 100644 --- a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue +++ b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue @@ -85,27 +85,47 @@ if ((column.value?.colOptions as any)?.formula_raw) { const source = computed(() => activeBase.value?.sources?.find((s) => s.id === meta.value?.source_id)) -const parsedTree = ref({ +const parsedTree = ref({ dataType: FormulaDataTypes.UNKNOWN, }) -watch( - () => vModel.value.formula || vModel.value.formula_raw, - async () => { - try { - const parsed = await validateFormulaAndExtractTreeWithType({ - formula: vModel.value.formula || vModel.value.formula_raw, - columns: (meta.value?.columns || []).slice(), - column: column.value ? { ...column.value } : undefined, - clientOrSqlUi: source.value?.type as any, - getMeta: async (modelId) => await getMeta(modelId), - }) +// Initialize a counter to track watcher invocations +let watcherCounter = 0 + +// Define the debounced async validation function +const debouncedValidate = useDebounceFn(async () => { + // Increment the counter for each invocation + watcherCounter += 1 + const currentCounter = watcherCounter + + try { + const parsed = await validateFormulaAndExtractTreeWithType({ + formula: vModel.value.formula || vModel.value.formula_raw, + columns: (meta.value?.columns || []).slice(), + column: column.value ? { ...column.value } : undefined, + clientOrSqlUi: source.value?.type as any, + getMeta: async (modelId) => await getMeta(modelId), + }) + + // Update parsedTree only if this is the latest invocation + if (currentCounter === watcherCounter) { parsedTree.value = parsed - } catch (e) { + } + } catch (e) { + // Update parsedTree only if this is the latest invocation + if (currentCounter === watcherCounter) { parsedTree.value = { dataType: FormulaDataTypes.UNKNOWN, } } + } +}, 300) + +// Watch the formula inputs and call the debounced function +watch( + () => vModel.value.formula || vModel.value.formula_raw, + () => { + debouncedValidate() }, )