首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

AJAX 多請求覆蓋問題:下拉框聯動的正確實現模式

     編輯:程式設計綜合問答

問題根源

代碼中使用全局變量 xmlHttp,發起多個並發請求時,後發請求覆蓋前請求的 xmlHttp 引用,導致回調函數讀取到錯誤的響應對象,最終只顯示最後一個請求結果。

解決方案:每請求一實例 + 閉包捕獲上下文

function loadSelectData(selectId, url, paramName, paramValue) {
    const xhr = new XMLHttpRequest(); // 局部變量,每調用一次創建一個
    xhr.open('GET', url + '?' + paramName + '=' + encodeURIComponent(paramValue), true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            document.getElementById(selectId).innerHTML = xhr.responseText;
        }
    };
    xhr.send();
}

// 使用示例:演出選擇後聯動時間、地點、票價
document.getElementById('showSelect').onchange = function() {
    const showId = this.value;
    loadSelectData('timeSelect', '/api/times', 'showId', showId);
    loadSelectData('placeSelect', '/api/places', 'showId', showId);
    loadSelectData('priceSelect', '/api/prices', 'showId', showId);
};

進階模式:Promise 封裝與錯誤處理

function fetchHTML(url, params) {
    const query = new URLSearchParams(params).toString();
    return fetch(url + '?' + query).then(r => r.ok ? r.text() : Promise.reject(r.status));
}

async function updateAll(showId) {
    try {
        const [times, places, prices] = await Promise.all([
            fetchHTML('/api/times', {showId}),
            fetchHTML('/api/places', {showId}),
            fetchHTML('/api/prices', {showId})
        ]);
        document.getElementById('timeSelect').innerHTML = times;
        document.getElementById('placeSelect').innerHTML = places;
        document.getElementById('priceSelect').innerHTML = prices;
    } catch (err) { console.error('聯動失敗', err); }
}

關鍵原則

  • 避免全局 XMLHttpRequest 實例。
  • 利用閉包或 fetch Promise 綁定請求上下文。
  • 並發請求互不干擾,回調各自更新對應 DOM。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved