promise以及async、await學習總結

孫小渃發表於2019-02-16

Promise/async、await幫我們解決了什麼

它給我們提供了一種新的非同步程式設計解決方案,同時避免了困擾已久的回撥地獄

// 非同步的處理可能會產生這樣的回撥地獄(第二個非同步操作和第一個非同步的結果有關係)
let Ajax = function(data, success, error){
  $.ajax({
      data: data,
      success: function(res){
        success(res)
      },
      error: function(err){
        error(err)
      }
  })
}
Ajax(data,function(res){
  Ajax(data,function(res){
    // 繼續迴圈回撥
  },function(err){})
},function(err){})
// 看看promise的處理方式
let promise = function (data) {
  return new Promise((resolve,reject) => {
      $.ajax({
          data: data,
          success: function(res){
              resolve(res)
          },
          error: function(err){
              reject(err)
          }
      })
  })
}
let data = {} // ajax請求引數
promise(data).then((res) => {return promise(res)}).catch(err => console.log(err)).then(res => console.log(res))
// async 、await的處理方式使得非同步操作更方便
(async function(){
let res = await promise(data)
let resp = await promise(res)
console.log(resp)
})()

Promise的方法總結

Promise.prototype.then()

Promise.prototype.catch()

Promise.prototype.finally()

Promise.all()

# 當存在多個沒有相關性的非同步操作時想一次性得到所有結果,可以使用promise.all()
Promise.all([p1,p2,p3])
只有當所有非同步操作狀態變為resolve的時候
返回所有值得陣列
當有一個返回reject的時候
返回值為第一個reject的值

Promise.race()

# 當存在多個沒有相關性的非同步操作時,想要獲得返回速度最快的非同步操作採用
Promise.race([p1,p2,p3])
該方法返回第一個有返回值的非同步操作的返回值(resolve或者reject)
Promise.race([new Promise((resolve, reject) => {
  console.log(`init p1`)
  setTimeout(()=>{
    console.log(`init p1 +`)
    resolve(`p1`)
  },2000)
}),new Promise((resolve, reject) => {
  console.log(`init p2`)
  setTimeout(()=>{
    console.log(`init p2 +`)
    resolve(`p2`)
  },1000)
})]).then(res=>{console.log(res)})
使用場景:設定一個請求的超時時間
Promise.race([new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(`1`)
    },2000)
}),new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject(new Error(`time out`))
    },1000)
})]).then((res=>console.log(res)))

Promise.resolve()

Promise.resolve(`111`).then(res=>console.log(res))

Promise.reject()

Promise.reject(`err`).catch(res=>console.log(res))

Promise.try()[目前只是一個提案]

# 【使用時機】對於一個方法如果不知道是同步非同步方法,但是想要用then來做後續操作,同時希望同步方法同步執行,非同步方法非同步執行。
# 等價方案
(async () => f())()
.then(res=>console.log(res))
.catch(err=>console.log(err))

async需要注意什麼

錯誤的捕獲

const f = () => console.log(`now`)
(async () => f())()
# async 會吃掉f()的錯誤,可以通過promise.catch()來捕獲
(async () => f())()
.then(res=>console.log(res))
.catch(err=>console.log(err))

參考

Promise
async/await

相關文章