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

JavaScript 非同步回調中獲取返回值的正確模式:Promise 化 DWR/Ajax 調用

     編輯:程式設計綜合問答

問題本質

policyDWR.pdsize(callback) 是典型的非同步 API,回調函數在未來某個時間執行。直接在外層函數 big() 中 return 回調內的變量會得到 undefined,因為同步代碼早已執行完畢。

錯誤示範

function big() {
    var flag;
    policyDWR.pdsize(function(args) { flag = args; });
    return flag; // 永遠 undefined
}

現代解決方案:Promise 包裝

// 通用包裝器
function dwrPromise(methodName, ...args) {
    return new Promise((resolve, reject) => {
        policyDWR[methodName]((result) => {
            if (result instanceof Error) reject(result);
            else resolve(result);
        }, ...args);
    });
}

// 使用 async/await(ES2017+)
async function big() {
    try {
        const args = await dwrPromise('pdsize');
        if (args === 1) return 1;
        if (args === 2) return 2;
        return args; // 或拋出異常
    } catch (err) {
        console.error('DWR 調用失敗', err);
        throw err;
    }
}

// 呼叫端
big().then(result => {
    console.log('big 返回:', result);
});

傳統回調風格(不推薦新代碼使用)

function big(callback) {
    policyDWR.pdsize(function(args) {
        if (args === 1) callback(1);
        else if (args === 2) callback(2);
        else callback(args);
    });
}

// 使用
big(function(result) {
    alert('結果: ' + result);
});

進階:統一錯誤處理與超時控制

function dwrWithTimeout(method, timeoutMs = 5000) {
    return Promise.race([
        dwrPromise(method),
        new Promise((_, reject) =>
            setTimeout(() => reject(new Error('DWR 請求超時')), timeoutMs)
        )
    ]);
}

核心原則

  1. 非同步不返回值,只傳遞續延:回調、Promise、async/await 都是續延傳遞風格 (CPS)。
  2. 邊界處理:網路失效、業務異常碼、超時,統一在 Promise 鏈中 catch。
  3. 漸進式遷移:舊代碼逐步包裝為 Promise,新代碼全面使用 async/await。

相關資源

  • MDN Using Promises
  • DWR 官方文檔:engine.js 中的 DWREngine.setErrorHandler 全域錯誤攔截
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved