Promise基本使用

Promise基本使用

const p = new Promise((resolve, reject) => { // 1)同步執(zhí)行的執(zhí)行器函數(shù)
  // 2) 在執(zhí)行器函數(shù)中啟動異步任務
  setTimeout(() => {
    // 3) 根據(jù)結果做不同處理
    const time = Date.now()
    // 3.1) 如果成功了, 調用resolve(), 指定成功的value, 變?yōu)閞esolved狀態(tài)
    if (time % 2 == 1) {
      resolve('成功的數(shù)據(jù) ' + time)
      console.log('resolve()之后')
    } else {//     3.2) 如果失敗了, 調用reject(), 指定失敗的reason, 變?yōu)閞ejected狀態(tài)
      reject('失敗的數(shù)據(jù) ' + time)
    }
  }, 1000);
})

// 4) 能promise指定成功或失敗的回調函數(shù)來獲取成功的vlaue或失敗的reason
p.then(
  value => {
    console.log('成功', value)
  },
  error => {
    console.log('失敗', error)
  }
)

Promise的API

  1. Promise構造函數(shù): Promise (excutor) {}
    excutor函數(shù): 同步執(zhí)行 (resolve, reject) => {}
    resolve函數(shù): 內部定義成功時我們調用的函數(shù) value => {}
    reject函數(shù): 內部定義失敗時我們調用的函數(shù) reason => {}
    說明: excutor會在Promise內部立即同步回調,異步操作在執(zhí)行器中執(zhí)行

  2. Promise.prototype.then方法: (onResolved, onRejected) => {}
    onResolved函數(shù): 成功的回調函數(shù) (value) => {}
    onRejected函數(shù): 失敗的回調函數(shù) (reason) => {}
    說明: 指定用于得到成功value的成功回調和用于得到失敗reason的失敗回調
    返回一個新的promise對象

  3. Promise.prototype.catch方法: (onRejected) => {}
    onRejected函數(shù): 失敗的回調函數(shù) (reason) => {}
    說明: then()的語法糖, 相當于: then(undefined, onRejected)

  4. Promise.resolve方法: (value) => {}
    value: 成功的數(shù)據(jù)或promise對象
    說明: 返回一個成功/失敗的promise對象

  5. Promise.reject方法: (reason) => {}
    reason: 失敗的原因
    說明: 返回一個失敗的promise對象

  6. Promise.all方法: (promises) => {}
    promises: 包含n個promise的數(shù)組
    說明: 返回一個新的promise, 只有所有的promise都成功才成功, 只要有一個失敗了就直接失敗

7.Promise.race方法: (promises) => {}
promises: 包含n個promise的數(shù)組
說明: 返回一個新的promise, 第一個完成的promise的結果狀態(tài)就是最終的結果狀態(tài)

例子

new Promise((resolve, reject) => {
  setTimeout(() => {
    // resolve(1)
    reject(2)
  }, 1000);
}).then(value => {
  console.log('onResolved()', value)
}/* , error=> {
  console.log('onRejected()', error)
} */).catch(error=> {
  console.log('onRejected2()', error)
})

此法來解決回調地獄

//回調地獄
doSomething(function (result) {
  // 第一個異步任務成功啟動第二個異步任務
  doSomethingElse(result, function (newResult) {
    // 第二個異步任務成功啟動第三個異步任務
    doThirdThing(newResult, function (finalResult) {
      // 第三個異步任務成功了
      console.log('Got the final result: ' + finalResult)
    }, failureCallback)
  }, failureCallback)
}, failureCallback)


//鏈式調用解決回調地獄
doSomething()
  .then(function (result) {
    return doSomethingElse(result)
  })
  .then(function (newResult) {
    return doThirdThing(newResult)
  })
  .then(function (finalResult) {
    console.log('Got the final result: ' + finalResult)
  })
  .catch(failureCallback)

Promise.all 全成功才行

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1)
  }, 1000);
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
const p4 = Promise.reject(4)
p1.then(value => console.log('p1 value', value))
p2.then(value => console.log('p2 value', value))
p3.catch(reason => console.log('p3 value', reason))
p4.catch(reason => console.log('p4 value', reason))

const pa = Promise.all([p1, p2, p3, p4])
// const pa = Promise.all([p1, p2])
pa.then(
  values => console.log('pa all onResolved()', values), // 數(shù)據(jù)的順序與promise數(shù)組順序一致,不是按先后
  reason => console.log('pa all onRejected()', reason),
)

Promise.race 誰先取誰

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1)
  }, 1000);
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
const p4 = Promise.reject(4)
p1.then(value => console.log('p1 value', value))
p2.then(value => console.log('p2 value', value))
p3.catch(reason => console.log('p3 value', reason))
p4.catch(reason => console.log('p4 value', reason))

const pr = Promise.race([p1, p3, p2])
//const pr = Promise.race([p2, p3, p1])
pr.then(
  value => console.log('pr race onResolved()', value),
  reason => console.log('pr race onRejected()', reason),
)

深入Promise

  1. 如何改變promise的狀態(tài)?
    (1)resolve(value): 如果當前是pendding就會變?yōu)閞esolved
    (2)reject(reason): 如果當前是pendding就會變?yōu)閞ejected
    (3)拋出異常: 如果當前是pendding就會變?yōu)閞ejected

  2. 一個promise指定多個成功/失敗回調函數(shù), 當promise改變?yōu)閷獱顟B(tài)時都會調用

const p = new Promise((resolve, reject) => {
  // resolve(1) // pending ==> resolved
  // reject(2) // pending ==> rejected
  // throw 3 // 執(zhí)行器中拋出異常  pending ==> rejected
})

p.then(
  value => console.log('onResolved()', value),
  reason => console.log('onRejected()', reason)
)
p.then(
  value => console.log('onResolved2()', value),
  reason => console.log('onRejected2()', reason)
)
console.log(p)
  1. 改變promise狀態(tài)和指定回調函數(shù)誰先誰后?
    (1)都有可能, 正常情況下是先指定回調再改變狀態(tài), 但也可以先改狀態(tài)再指定回調
    (2)如何先改狀態(tài)再指定回調?
    在執(zhí)行器中直接調用resolve()/reject()
    延遲更長時間才調用then()
    (3)什么時候才能得到數(shù)據(jù)?
    ①如果先指定的回調, 那當狀態(tài)發(fā)生改變時, 回調函數(shù)就會調用, 得到數(shù)據(jù)
    ②如果先改變的狀態(tài), 那當指定回調時, 回調函數(shù)就會調用, 得到數(shù)據(jù)
const p = new Promise((resolve, reject) => { // 同步回調
  console.log('excutor()')
  // 啟動異步任務
  setTimeout(() => {
    resolve(1)  // pending ==> resolved  value為1
    console.log('resolve()改變狀態(tài)后')
    // reject()
  }, 1000)
})

setTimeout(() => {
  p.then( // 先指定回調函數(shù), 內部選將回調函數(shù)保存起來
    value => { // 成功/失敗的回調函數(shù)是異步執(zhí)行的, 需要放入隊列將來執(zhí)行
      console.log('onResolved()', value)
    }
  )
},5000);
console.log('new Promise()之后')
const p = new Promise((resolve, reject) => { // 同步回調
  console.log('excutor()')
  // 啟動異步任務
  setTimeout(() => {
    resolve(1)  // pending ==> resolved  value為1
    console.log('resolve()改變狀態(tài)后')
    // reject()
  }, 5000)
})

setTimeout(() => {
  p.then( // 先指定回調函數(shù), 內部選將回調函數(shù)保存起來
    value => { // 成功/失敗的回調函數(shù)是異步執(zhí)行的, 需要放入隊列將來執(zhí)行
      console.log('onResolved()', value)
    }
  )
},1000);
console.log('new Promise()之后')

  1. promise的then()返回一個新的promise, 可以開成then()的鏈式調用,通過then的鏈式調用串連多個同步/異步任務
new Promise((resolve, reject) => {
  // 啟動任務1(異步)
  console.log('啟動任務1(異步)')
  setTimeout(() => {
    resolve(1)
  }, 1000)
}).then(value => {
  console.log('任務1成功的value為', value)
  // 執(zhí)行任務2(同步)
  console.log('執(zhí)行任務2(同步)')
  return 2
}).then(value => {
  console.log('任務2成功的vlaue為', value)
  // 執(zhí)行任務3(異步)
  return new Promise((resolve, reject) => {
    console.log('調動任務3(異步)')
    setTimeout(() => {
      resolve(3)
    }, 1000);
  })
}).then(value => {
  console.log('任務3成功的value為: ', value)
})

  1. 中斷promise鏈
    (1)當使用promise的then鏈式調用時, 在中間中斷, 不再調用后面的回調函數(shù)
    (2)辦法: 在回調函數(shù)中返回一個pendding狀態(tài)的promise對象
new Promise((resolve, reject) => {
  // resolve(1)
  reject(2)
}).then(
  value => console.log('onResolved1()', value),
  // reason => {throw reason}
).then(
  value => console.log('onResolved2()', value),
 // reason => Promise.reject(reason)
).then(
  value => console.log('onResolved3()', value),
  // reason => {throw reason}
).catch(reason => {
  console.log('onRejected1()', reason)
  // throw reason
  return new Promise(() => {}) // 返回一個pending狀態(tài)的promise ==> 中斷promise鏈接  
}).then(
  value => console.log('onResolved4()', value),
  reason => console.log('onRejected2()', reason)
)

文章同步我的博客

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容