Promise 的特點 - daniel-qa/Vue GitHub Wiki
Promise 鏈式呼叫(最基礎、最通用)
Vue 2 最常見的方式:
this.$api.mainTask(params)
.then(res => {
if (res.success) {
// 第一個 API 成功後再執行刷新畫面
return this.$api.refreshView()
}
})
.then(refreshRes => {
this.tableData = refreshRes.data // 更新畫面資料
})
.catch(err => {
console.error(err)
this.$message.error('操作失敗')
})
優點: 無需修改 Vue 設定,適合大多數場景
缺點: 可讀性略低,巢狀較多時會不好維護
Promise.all
- 範例
Promise.all([
this.$api.serviceAuth.teacherSpace(), // 第一個 Promise
this.$api.serviceAuth.studentSpace(), // 第二個 Promise
this.$api.serviceAuth.adminSpace() // 第三個 Promise
])
.then(([teacher, student, admin]) => {
console.log("老師資料:", teacher)
console.log("學生資料:", student)
console.log("管理員資料:", admin)
})
Promise.all 會依 陣列順序 將每個 Promise 的結果放進 then 的參數陣列。
[teacher, student, admin] 對應 [第一個 Promise, 第二個 Promise, 第三個 Promise]。
Promise.all 的結果 只能在 then 裡面或用 await 拿到。 外面直接拿是拿不到的。
- 什麼時候用 Promise.all?
需要同時發多個請求,而且結果要一起處理時。
節省時間(並行,而不是一個一個等)。
缺點:一個錯誤就會讓整批失敗。
Promise
- 範例:
基本格式
new Promise((resolve, reject) => {
this.$api.serviceAuth.teacherSpace()
.then(res => {
resolve(res) // API 回傳成功,這裡把結果傳給 then
})
.catch(err => {
reject(err) // API 失敗,丟給 catch
})
})
resolve(res) 就是把 API 成功結果「傳給外層 Promise」
這樣外層的 .then() 就能拿到這個結果。
- 範例2
new Promise((resolve, reject) => {
const success = false
if (success) {
resolve("OK") // 成功 → 走 then
} else {
reject("出錯了") // 失敗 → 走 catch
}
})
.then(res => console.log("成功:", res))
.catch(err => console.error("錯誤:", err))
resolve() → 表示這件事成功
reject() → 表示失敗,需要在 .catch() 處理
- Promise 範例
let params = {
action: "upd",
school_code: this.$store.state.userInfo.schoolCode,
teachers: this.updTeachers
}
this.isLoading = true
this.$api.spaceAuth.teacherSpace(params).then(
res => {
this.$Message.success(this.$t('teachermgmt.message.saveOk'))
this.$store.commit('user/updTeacher', this.updTeachers)
this.getTeachersTemp()
},
err => {
}
).finally(() => {
this.isLoading = false
})
這段程式碼就是在消費 (consume) 一個 Promise。
this.$api.spaceAuth.teacherSpace 是一個發出網路請求的函式,它就是那個披薩店員,會給你一張 Promise 的收據。
當請求成功,res 裡會拿到回傳的資料,執行 then 裡的第一個函式。
當請求失敗,err 裡會拿到錯誤訊息,執行 then 裡的第二個函式。
不管結果如何,最後都會執行 finally 裡的程式碼,把 isLoading 設為 false。
程式碼本身不是 Promise,而是利用 Promise 的機制來優雅地處理非同步操作。
res 是成功的回傳值 ,err 是錯誤的回傳值
在 Promise 的 .then() 方法裡:
res 就是 resolved(成功)時的回傳值。
err 就是 rejected(失敗)時的回傳值。
- resolved 和 rejected 是 Promise 的兩個最終狀態,代表一個非同步操作的最終結果。
resolved (已實現)
當一個非同步操作成功完成時,Promise 的狀態就會變成 resolved。這代表:
任務順利完成。
你得到了一個預期的結果或資料。
rejected (已拒絕)
當一個非同步操作失敗或出錯時,Promise 的狀態就會變成 rejected。這通常是因為:
任務無法完成。
發生了意料之外的錯誤。
- Promise 只有三種狀態:
pending (待定):剛開始,還在等待結果。
resolved (已實現):成功了,得到結果。
rejected (已拒絕):失敗了,得到錯誤。
一個 Promise 一旦從 pending 變成 resolved 或 rejected,它的狀態就不會再改變了。這就是為什麼 Promise 被稱為「一次性」的非同步處理機制。
Promise 的特点
-
内置:Promise 是 ECMAScript 6(ES6)引入的标准功能,所有现代浏览器和 Node.js 环境都原生支持它。
-
状态管理:Promise 有三种状态:待定(Pending)、已解决(Fulfilled)、已拒绝(Rejected)。
-
链式调用:可以通过 then() 和 catch() 方法链式处理结果和错误,使得代码更清晰。
-
错误处理:可以集中处理错误,减少回调地狱的情况。
-
例子
const myPromise = new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
const success = true; // 模拟成功或失败
if (success) {
resolve('成功!');
} else {
reject('失败!');
}
}, 1000);
});
// 使用 Promise
myPromise
.then(result => {
console.log(result); // 输出: 成功!
})
.catch(error => {
console.error(error); // 输出: 失败!
});
总结
Promise 是 JavaScript 的一部分,用于处理异步操作。它并不是一个外部库或套件,而是语言本身的一种特性。
resolve 和 reject
-
resolve(value):用于将 Promise 的状态从“待定”(Pending)更改为“已解决”(Fulfilled),并将 value 作为成功的结果传递下去。
-
reject(reason):用于将 Promise 的状态从“待定”(Pending)更改为“已拒绝”(Rejected),并将 reason 作为失败的原因传递下去。
-
处理结果:
使用 then() 方法处理成功的结果。
使用 catch() 方法处理失败的原因。
- 总结
resolve 和 reject 是 Promise 中的关键方法,用于改变 Promise 的状态和传递结果或错误信息。