Promise快速上手

概述

回調(diào)函數(shù)JavaScript異步編程的根基,但如果我們直接使用傳統(tǒng)回調(diào)方式去完成復(fù)雜的異步流程,就無(wú)法避免回調(diào)函數(shù)嵌套的問(wèn)題,即常說(shuō)的“回調(diào)地獄”。

為了解決這個(gè)問(wèn)題,CommonJS社區(qū)提出了Promise規(guī)范,在ES2015中被標(biāo)準(zhǔn)化,成為語(yǔ)言規(guī)范。

Promise就是一個(gè)對(duì)象,用來(lái)表示一個(gè)異步任務(wù)在最終結(jié)束后,是成功還是失敗。類似于內(nèi)部對(duì)外界做出了一個(gè)“承諾”,一開始,處于待定狀態(tài)(Pending,最終有可能是成功(Fulfilled狀態(tài),也有可能是失?。?code>Rejected)狀態(tài),最終的結(jié)果狀態(tài)明確后,都會(huì)有相應(yīng)的任務(wù)被執(zhí)行,一但結(jié)果明確,就不可能再發(fā)生改變

快速上手

const promise = new Promise(function (resolve, reject) {
  // 這里用于兌現(xiàn)承諾
  // 這里的代碼會(huì)被同步執(zhí)行,屬于同步任務(wù)
  console.log(1)
  resolve(100) // 承諾達(dá)成
  //reject(new Error('promise rejected')) // 承諾失敗
})
// then 方法接收兩個(gè)參數(shù),第一個(gè)是成功回調(diào),第二個(gè)是失敗回調(diào)
promise.then(function(value) {
  // promise的回調(diào)屬于微任務(wù)
  console.log('resolved', value)
}, function (error) {
  console.log('rejected', error)
})

如果在回調(diào)函數(shù)中又需要發(fā)起一次異步任務(wù),循環(huán)往復(fù),依然會(huì)出現(xiàn)“回調(diào)地獄”,這是使用Promise的一個(gè)常見誤區(qū),對(duì)于這種情況,我們應(yīng)該借助于Promise then方法鏈?zhǔn)秸{(diào)用的特點(diǎn),保證異步任務(wù)的扁平化。

鏈?zhǔn)秸{(diào)用

  • then方法內(nèi)部會(huì)返回一個(gè)全新的Promise對(duì)象
  • 后面的then方法就是在為上一個(gè)then返回的Promise注冊(cè)回調(diào)
  • 前面then方法中回調(diào)函數(shù)的返回值會(huì)作為后面then方法回調(diào)的參數(shù)
  • 如果回調(diào)中返回的是Promise,那后面then方法的回調(diào)會(huì)等待它的結(jié)束
  • 使用catch捕獲異??梢圆东@到Promise鏈條上的異常,但上一個(gè)示例中的第二個(gè)參數(shù)捕獲異常函數(shù)只是給第一個(gè)Promise注冊(cè)了失敗回調(diào)
const promise = new Promise(function (resolve, reject) {
  resolve(100)
})
promise.then(function(value) {
  console.log('resolved', value) 
}).then(function (value){
  console.log(value) // undefined
  throw new Error()
}).catch(function (error) {
  // catch 方法捕獲異常
  console.log('error') // 'error'
})

靜態(tài)方法

resolve
  • 該方法的作用是,快速的把一個(gè)值轉(zhuǎn)換成一個(gè)Promise對(duì)象,例如Promise.resolve('foo')
      Promise.resolve('foo').then(value => {
        console.log(value) // 'foo'
      })
    
  • 如果resolve的參數(shù)是一個(gè)promise,則會(huì)原樣返回這個(gè)promise
      let promise = new Promise((resolve, reject) => {})
      let promise2 = Promise.resolve(promise)
      console.log(promise === promise2) // true
    
reject
  • resolve類似,會(huì)快速創(chuàng)建一個(gè)狀態(tài)為失敗的Promise對(duì)象
all
  • 參數(shù)為一個(gè)數(shù)組,當(dāng)內(nèi)部所有Promise都執(zhí)行完畢后,返回的Promise狀態(tài)才會(huì)改變,若有一個(gè)Promise狀態(tài)為失敗,則返回的Promise對(duì)象狀態(tài)也會(huì)變成失敗,不再等待其它的Promise
let p1 = new Promise((resolve, reject) => {
  resolve('p1')
})
let p2 = new Promise((resolve, reject) => {
setTimeout(function () {
    resolve('p2')
}, 1000)
  
})
let p3 = new Promise((resolve, reject) => {
  resolve('p3')
})
Promise.all([p1, p2, p3]).then(res => {
  // 返回的結(jié)果與參數(shù)Promise對(duì)應(yīng)
  console.log(res) // ["p1", "p2", "p3"]
}).catch(error => {
  console.log(error)
})

race

all方法是等待所有任務(wù)結(jié)束,而race只會(huì)等待第一個(gè)結(jié)束的任務(wù)

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

友情鏈接更多精彩內(nèi)容