function getA() {
var a;
$.ajax({
type: "POST",
url: "*******",
async: false, // ❌ 同步請求:阻塞主線程、體驗差、已棄用
success: function(result) {
a = result;
}
});
return a; // 同步模式下能返回,但強烈不推薦
}
return a 執行時回調**尚未執行**,a 仍為 undefined
function getA(callback) {
$.ajax({
type: "POST",
url: "/api/getData",
data: { id: 1234 },
success: function(result) {
callback(null, result); // 成功回調
},
error: function(xhr, status, error) {
callback(error); // 失敗回調
}
});
}
// 使用
getA(function(err, data) {
if (err) return console.error(err);
console.log('拿到數據:', data);
// 後續邏輯在這裡寫
});
function getA() {
return new Promise((resolve, reject) => {
$.ajax({
type: "POST",
url: "/api/getData",
data: { id: 1234 },
success: resolve,
error: reject
});
});
}
// 使用 .then 鏈式調用
getA()
.then(data => {
console.log('數據:', data);
return processData(data);
})
.then(processed => {
// 下一步
})
.catch(err => console.error(err));
// 需環境支持 (Babel/現代瀏覽器/Node.js)
async function handleData() {
try {
const data = await getA(); // 這裡「暫停」等待,不阻塞主線程
console.log('數據:', data);
// 後續同步風格代碼
} catch (err) {
console.error(err);
}
}
handleData();
async function getA() {
const response = await fetch('/api/getData', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: 1234 })
});
if (!response.ok) throw new Error('HTTP ' + response.status);
return response.json();
}
// 使用同方案三
// JS 事件循環模型
// 主線程執行棧 → 微任務隊列 → 宏任務隊列
function syncWait() {
// ❌ 無法實現:JS 無 sleep/await 原語阻塞主線程
// while (!done) {} // 死循環會凍結頁面,事件循環無法處理網絡回調
}
**本質**:JS 單線程,**異步操作結果通過事件循環投遞到回調/微任務**,無法在發起函數中同步返回。
| 模式 | 優點 | 缺點 | 推薦場景 |
|---|---|---|---|
| 回調函數 | 兼容所有環境、無依賴 | 回調地獄、錯誤處理分散 | 舊項目、簡單場景 |
| Promise | 鏈式調用、統一錯誤處理、可組合 | 語法稍繁瑣 | 現代項目標準 |
| async/await | 同步寫法、易讀、try/catch 統一異常 | 需 ES2017+ 或轉譯 | 新項目首選 |
| 同步 AJAX | 代碼看起來同步 | 阻塞主線程、已棄用、體驗極差 | ❌ 絕對禁止 |
**核心原則**:擁抱異步,不要試圖同步化。將「獲取數據後做什麼」寫在回調/then/await 後面。