ES6異步解決方法:Promise與async

Promise

Promise 對象是由關鍵字 new 及其構造函數來創建的。一共有三種狀態,分別爲pending(進行中)、fulfilled(已成功)和rejected(已失敗)。創建示例如下:

const promise = new Promise((resolve, reject) => {
    // do something here ...
    if (success) {
        resolve(value); // fulfilled
    } else {
        reject(error); // rejected
    }
});

由上述代碼我們可知:
該構造函數接收兩個函數作爲參數,分別是resolvereject
當異步操作執行成功後,會將異步操作結果作爲參數傳入resolve函數並執行,此時 Promise對象狀態從pending變爲fulfilled
失敗則會將異步操作的錯誤作爲參數傳入reject函數並執行,此時 Promise對象狀態從pending變爲rejected

接下來,通過then方法,分別指定resolved狀態和rejected狀態的回調函數。

promise.then(function(value) {
      // success
  }, function(error) {
      // failure
  });

then方法可以接收兩個回調函數作爲參數,第一個回調函數就是fulfilled狀態時調用;第二個回調函數就是rejected時調用。這邊的第二個參數是可選的,不一定要提供。

Promise鏈式寫法:

const setDelaySecond = (seconds) => {
  return new Promise((resolve, reject)=>{
      if (typeof seconds != 'number' || seconds > 10) reject(new Error('參數必須是number類型,並且小於等於10'));
      setTimeout(()=> {
        resolve(`我延遲了${seconds}秒後輸出的,是第二個函數`)
      }, seconds * 1000)
  })
}
setDelay(2000)
.then((result)=>{
  console.log(result)
  console.log('我進行到第一步的');
  return setDelaySecond(3)
})
.then((result)=>{
  console.log('我進行到第二步的');
  console.log(result);
}).catch((err)=>{
  console.log(err);
})

 Async/await

async/await是一對好基友,缺一不可,他們的出生是爲Promise服務的。可以說async/await是Promise的爸爸,進化版。

async聲明的函數的返回本質上是一個Promise

什麼意思呢?就是說你只要聲明瞭這個函數是async,那麼內部不管你怎麼處理,它的返回肯定是個Promise。

看下列例子:

(async function () {
    return '我是Promise'
})()
// 返回是Promise
//Promise {<resolved>: "我是Promise"}

所以你想像一般function的返回那樣,拿到返回值,原來的思維要改改了!你可以這樣拿到返回值:

const demo = async function () {
    return Promise.resolve('我是Promise');
    // 等同於 return '我是Promise'
    // 等同於 return new Promise((resolve,reject)=>{ resolve('我是Promise') })
}
demo.then(result=>{
    console.log(result) // 這裏拿到返回值
})

上述三種寫法都行,要像對待Promise一樣去對待async的返回值。

注意:await 命令後面的 Promise 對象,運行結果可能是 rejected,所以最好把 await 命令放在 try...catch 代碼塊中。

async function myFunction() {
  try {
    await somethingThatReturnsAPromise();
  } catch (err) {
    console.log(err);
  }
}

// 另一種寫法

async function myFunction() {
  await somethingThatReturnsAPromise().catch(function (err){
    console.log(err);
  });
}

 

await 命令只能用在 async 函數之中,如果用在普通函數,就會報錯。



async function dbFuc(db) {
  let docs = [{}, {}, {}];

  // 報錯
  docs.forEach(function (doc) {
    await db.post(doc);
  });
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章