国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

使用ES2017 async/await函數的注意點

libxd / 2025人閱讀

摘要:正常函數異常函數注意當返回值本身就是一個對象時,函數的并不會對返回值進行二次包裝。總是按順序執行使用函數之前,我們還得搞清楚它的運行機制。因此在函數中的并不會掛起整個函數的執行。

隨著node 7.6.0正式實裝async/await函數,js的異步編程變的比以往更加容易。但是,在我們全面投入async/await的懷抱之前,有必要對這個特性做一些細致的了解。

書寫形式

基本上,任何一個函數都可以成為async函數,以下都是合法的書寫形式:

函數聲明
async function foo () {}

函數表達式
const foo = async function () {}

方法定義
const obj = { async foo () {} }

箭頭函數
async () => {}

async函數總是返回Promise

即使返回值只是一個primitive值,async函數也會通過return自動將返回值包裝成一個Promise對象返回。
因此,下面兩組函數是等價的。

正常 (Fulfill)
// async函數
async function foo () {
  return "a"
}

// Promise
function foo () {
  return Promise.resolve("a")
}
異常 (Reject)
// async函數
async function foo () {
  throw new Error("error")
}

// Promise
function foo () {
  return Promise.reject(new Error("error"))
}

注意:當返回值本身就是一個Promise對象時,async函數的return并不會對返回值進行二次包裝。

await總是按順序執行

使用async函數之前,我們還得搞清楚它的運行機制。尤其是在執行順序上,完全用同步的思維也許并不適用于async函數。

考慮下面的代碼

function asyncGet (x) {
  return new Promise(resolve => setTimeout(() => {
    console.log("a")
    resolve(x)
  }, 500))
}

async function test () {
  console.log("b")
  const x = 3 + 5
  console.log(x)

  const a = await asyncGet(1)
  console.log(a)

  const b = await asyncGet(2)
  console.log(b)

  console.log("c")  
  return a + b
}

const now = Date.now()
console.log("d")
test().then(x => {
  console.log(x)
  console.log(`elapsed: ${Date.now() - now}`)
})
console.log("f")

async函數和普通函數一樣按順序執行,同時,在執行到await語句時,返回一個Promise對象

await可以理解為將async函數掛起,直到等待的Promise被fulfill或者reject,再繼續執行之后的代碼

async函數的返回值和普通Promise沒有區別

因此,上面代碼輸出應該是

d
b
8
f
a
1
a
2
c
3
elapsed: 1010

注意 d 和 f 中間的輸出

讓我們再來看一個混合了Promise的版本。

function asyncGet (x) {
  return new Promise(resolve => setTimeout(() => {
    console.log("a")
    resolve(x)
  }, 500))
}

async function test () {
  console.log("b")
  const x = 3 + 5
  console.log(x)

  const [a, b] = await Promise.all([
    asyncGet(1),
    asyncGet(2)
  ])

  console.log("c")  
  return a + b
}

const now = Date.now()
console.log("d")
test().then(x => {
  console.log(x)
  console.log(`elapsed: ${Date.now() - now}`)
})
console.log("f")

輸出結果

d
b
8
f
a
a
c
3
elapsed: 509

注意到elapsed的差別了嗎?這就是為什么我們說await總是順序執行的。不同的await之間無法并行執行,想要真正的完全異步還得借助類似Promise.all這樣的方法。

async函數和callback

await只能能影響直接包裹它的async函數。因此在callback函數中的await并不會掛起整個async函數的執行。

一種常見的錯誤

async function getAll (vals) {
  return vals.map(v => await asyncGet(v))
}

這段代碼有語法錯誤,await并不在async函數內部。如果給map的callback加上async呢?

async function getAll (vals) {
  return vals.map(async v => await asyncGet(v))
}

這段代碼雖然能執行,但還有兩個問題。

返回一個Promise對象的數組,并不是我們期待的value數組

await只會暫停map的callback,因此map完成時,不能保證asyncGet也全部完成

正確的寫法還得借助Promise.all

async function getAll (vals) {
  return Promise.all(vals.map(v => asyncGet(v)))
}
總結

從上我們可以看出,Promiseasync函數的基礎,想要愉快的使用async函數,必須對Promise有比較深入的理解。甚至一些常見的任務,僅僅依靠async函數無法實現。
希望大家看完本文后能對async函數有個更全面的認識,這樣使用起來才會更加順手。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86812.html

相關文章

  • 理解ES7中async函數

    摘要:什么是標準引入了函數,使得異步操作變得更加方便。顧名思義是異步的意思,用于聲明一個函數是異步的。的作用正常情況下,命令后面是一個對象。表示函數等待返回結果了,再繼續執行。上面便是一種錯誤用法,并沒有在函數執行上下文中,而是在的回調函數中。 什么是Async、await ES2017 標準引入了 async 函數,使得異步操作變得更加方便。async顧名思義是異步的意思,用于聲明一個函數...

    curried 評論0 收藏0
  • ES2017異步函數現已正式可用

    摘要:標準已于年月份正式定稿了,并廣泛支持最新的特性異步函數。為了領會,我們需要回到普通回調函數中進一步學習。從此編寫回調函數不再那么痛苦。回調是一個函數,可以將結果傳遞給函數并在該函數內進行調用,以便作為事件的響應。 ES2017標準已于2017年6月份正式定稿了,并廣泛支持最新的特性:異步函數。如果你曾經被異步 JavaScript 的邏輯困擾,這么新函數正是為你設計的。 異步函數或多或...

    android_c 評論0 收藏0
  • 前后分離模型之封裝 Api 調用

    摘要:和異步處理調用訪問數據采用的方式,這是一個異步過程,異步過程最基本的處理方式是事件或回調,其實這兩種處理方式實現原理差不多,都需要在調用異步過程的時候傳入一個在異步過程結束的時候調用的接口。 Ajax 和異步處理 調用 API 訪問數據采用的 Ajax 方式,這是一個異步過程,異步過程最基本的處理方式是事件或回調,其實這兩種處理方式實現原理差不多,都需要在調用異步過程的時候傳入一個在異...

    trilever 評論0 收藏0
  • ECMAScript 2016,2017和2018中新增功能示例

    摘要:,和中新增功能的示例原文鏈接翻譯鏈接始終緊跟的最新功能是很難的,更難的是找到有用的代碼示例。和其他雙字節字符上的和和其它雙字節字符串使用的多字節表示。所以和可能無法按照預期的工作。提醒展開運算符用于等號的右側,解構運算符用于等號的左側。 ECMAScript 2016,2017和2018中新增功能的示例 原文鏈接: medium.freecodecamp.org翻譯鏈接:https:/...

    _Dreams 評論0 收藏0
  • asyncawait詳解

    摘要:異步函數是和的組合,基本上,它們是對的更高級別的抽象。引入的原因它們降低了對一些固定語法樣板的要求,打破了鏈式不能切斷鏈式的限制。引入來解決著名的回調地獄問題,但是因為他們自身的復雜性,引入了更復雜的語法。 1、簡介 需先了解 Promise 【鏈接地址】 JavaScript 中的異步函數方法。 JavaScript 在很短的時間內從回調演變為 Promises ,從 ES2...

    Simon_Zhou 評論0 收藏0

發表評論

0條評論

libxd

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<