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 的状态和传递结果或错误信息。