feat: centralize config refresh handling and prevent races

This commit is contained in:
hkfires
2025-11-21 11:34:12 +08:00
parent 608be95020
commit 1edafc637a
3 changed files with 43 additions and 3 deletions

28
app.js
View File

@@ -68,6 +68,9 @@ class CLIProxyManager {
// 状态更新定时器 // 状态更新定时器
this.statusUpdateTimer = null; this.statusUpdateTimer = null;
this.lastConnectionStatusEmitted = null; this.lastConnectionStatusEmitted = null;
this.isGlobalRefreshInProgress = false;
this.registerCoreEventHandlers();
// 日志自动刷新定时器 // 日志自动刷新定时器
this.logsRefreshTimer = null; this.logsRefreshTimer = null;
@@ -149,6 +152,7 @@ class CLIProxyManager {
init() { init() {
this.initUiVersion(); this.initUiVersion();
this.initializeTheme(); this.initializeTheme();
this.registerCoreEventHandlers();
this.registerSettingsListeners(); this.registerSettingsListeners();
this.registerUsageListeners(); this.registerUsageListeners();
if (typeof this.registerLogsListeners === 'function') { if (typeof this.registerLogsListeners === 'function') {
@@ -173,6 +177,30 @@ class CLIProxyManager {
} }
} }
registerCoreEventHandlers() {
if (!this.events || typeof this.events.on !== 'function') {
return;
}
this.events.on('config:refresh-requested', async (event) => {
const detail = event?.detail || {};
const forceRefresh = detail.forceRefresh !== false;
// 避免并发触发导致重复请求
if (this.isGlobalRefreshInProgress) {
return;
}
await this.runGlobalRefresh(forceRefresh);
});
}
async runGlobalRefresh(forceRefresh = false) {
this.isGlobalRefreshInProgress = true;
try {
await this.loadAllData(forceRefresh);
} finally {
this.isGlobalRefreshInProgress = false;
}
}
// 检查主机名并隐藏 OAuth 登录框 // 检查主机名并隐藏 OAuth 登录框
checkHostAndHideOAuth() { checkHostAndHideOAuth() {
const hostname = window.location.hostname; const hostname = window.location.hostname;

View File

@@ -209,7 +209,9 @@ export const configEditorModule = {
this.showNotification(i18n.t('config_management.save_success'), 'success'); this.showNotification(i18n.t('config_management.save_success'), 'success');
this.updateConfigEditorStatus('success', i18n.t('config_management.status_saved')); this.updateConfigEditorStatus('success', i18n.t('config_management.status_saved'));
this.clearCache(); this.clearCache();
await this.loadAllData(true); if (this.events && typeof this.events.emit === 'function') {
this.events.emit('config:refresh-requested', { forceRefresh: true });
}
} catch (error) { } catch (error) {
const errorMessage = `${i18n.t('config_management.status_save_failed')}: ${error.message}`; const errorMessage = `${i18n.t('config_management.status_save_failed')}: ${error.message}`;
this.updateConfigEditorStatus('error', errorMessage); this.updateConfigEditorStatus('error', errorMessage);

View File

@@ -12,6 +12,11 @@ export const languageModule = {
}, },
toggleLanguage() { toggleLanguage() {
if (this.isLanguageRefreshInProgress) {
return;
}
this.isLanguageRefreshInProgress = true;
const currentLang = i18n.currentLanguage; const currentLang = i18n.currentLanguage;
const newLang = currentLang === 'zh-CN' ? 'en-US' : 'zh-CN'; const newLang = currentLang === 'zh-CN' ? 'en-US' : 'zh-CN';
i18n.setLanguage(newLang); i18n.setLanguage(newLang);
@@ -19,8 +24,13 @@ export const languageModule = {
this.updateThemeButtons(); this.updateThemeButtons();
this.updateConnectionStatus(); this.updateConnectionStatus();
if (this.isLoggedIn && this.isConnected) { if (this.isLoggedIn && this.isConnected && this.events && typeof this.events.emit === 'function') {
this.loadAllData(true); this.events.emit('config:refresh-requested', { forceRefresh: true });
} }
// 简单释放锁,避免短时间内的重复触发
setTimeout(() => {
this.isLanguageRefreshInProgress = false;
}, 500);
} }
}; };