最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS異步編程之generator與async/await語法糖詳解

 更新時(shí)間:2022年11月02日 09:29:17   作者:開水泡飯  
這篇文章主要為大家詳細(xì)介紹了JS異步編程中g(shù)enerator與async/await語法糖的使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下

Generator 異步方案

相比于傳統(tǒng)回調(diào)函數(shù)的方式處理異步調(diào)用,Promise最大的優(yōu)勢就是可以鏈?zhǔn)秸{(diào)用解決回調(diào)嵌套的問題。但是這樣寫依然會有大量的回調(diào)函數(shù),雖然他們之間沒有嵌套,但是還是沒有達(dá)到傳統(tǒng)同步代碼的可讀性。如果以下面的方式寫異步代碼,它是很簡潔,也更容易閱讀的。

// like sync mode

try{
  const value1 = ajax('/api/url1')
  console.log(value1)
  const value2 = ajax('/api/url1')
  console.log(value2)
  const value3 = ajax('/api/url1')
  console.log(value3)
  const value4 = ajax('/api/url1')
  console.log(value4)
  const value5 = ajax('/api/url1')
  console.log(value5)
}catch(err){
  console.log(err)
}

在ES2015提供了生成器函數(shù)(Generator Function)它與普通函數(shù)的語法差別在于,在function語句之后和函數(shù)名之前,有一個(gè)“*”作為生成器函數(shù)的標(biāo)示符。

在我們?nèi)フ{(diào)用生成器函數(shù)的時(shí)候他并不會立即去執(zhí)行這個(gè)函數(shù),而是會得到一個(gè)生成器對象,直到我們手動調(diào)用對象的next 方法,函數(shù)體才會開始執(zhí)行,我們可以使用關(guān)鍵字yield去向外返回一個(gè)值,我們可以在next方法的返回值中去拿到這個(gè)值。另外再返回的屬性中還有一個(gè)done關(guān)鍵字來表示生成器是否執(zhí)行完了,

yield不會像return一樣去結(jié)束函數(shù)的執(zhí)行,只是暫停函數(shù)的執(zhí)行,直到外接下一次調(diào)用next方法時(shí)才會繼續(xù)從yield位置往下執(zhí)行

function * foo () {
  console.log('start')
    yield 'foo'
}

???????const generator = foo()

const result = generator.next()

調(diào)用next方法的時(shí)候傳入了參數(shù)的話,所傳入的參數(shù)會作為yield關(guān)鍵字的返回值

function * foo () {
  console.log('start')
    // 我可以在這里接收next傳入的參數(shù)
    const res = yield 'foo'
  console.log(res) // 這是我傳入的參數(shù)
}

const generator = foo()

const result = generator.next('這是我傳入的參數(shù)')
console.log(result) // { value: 'foo', done: false }

如果我們調(diào)用了生成器函數(shù)的throw方法,這個(gè)方法會給生成器函數(shù)內(nèi)部拋出一個(gè)異常

function * foo () {
  console.log('start')
  // 我可以在這里接收next傳入的參數(shù)
  try {
    const res = yield 'foo'
    console.log(res) // 這是我傳入的參數(shù)
  } catch (err) {
    console.log(err.message) // 拋出錯(cuò)誤
  }
}

const generator = foo()

const result = generator.next('這是我傳入的參數(shù)')
console.log(result)

generator.throw(new Error('拋出錯(cuò)誤'))

利用生成器函數(shù)和Promise來實(shí)現(xiàn)異步編程的體驗(yàn)

function ajax(url) {
  return new Promise((resove, reject) => {
    var xhr = new XMLHttpRequest()
    xhr.open('GET', url)
    // 新方法可以直接接受一個(gè)j對象
    xhr.responseType = 'json'
    xhr.onload = function () {
      if (this.status === 200) {
        resove(this.response)
      } else {
        reject(new Error(this.statusText))
      }
    }
    xhr.send()
  })
}

function* main() {
  const user1 = yield ajax('/json1.json')
  console.log(user1)

  const user2 = yield ajax('/json2.json')
  console.log(user2)

  const user3 = yield ajax('/json3.json')
  console.log(user3)
}

const g = main()
const result = g.next()

result.value.then(data => {
  const result2 = g.next(data)

  if (result2.done) return
  result2.value.then(data2 => {
    const result3 = g.next(data2)

    if (result3.done) return
    result3.value.then(data3 => {
      g.next(data3)
    })
  })
})

很明顯生成器的執(zhí)行器可以使用遞歸的方式去調(diào)用

const g = main()

function handleResult(result) {
  if (result.done) return
  result.value.then(data => {
    handleResult(g.next(data))
  }, err => {
    g.throw(err)
  })
}

handleResult(g.next())

生成器函數(shù)的調(diào)用其實(shí)都是差不多的,所以我們可以寫一個(gè)比較通用的執(zhí)行器

function co(generator) {
  const g = generator()

  function handleResult(result) {
    if (result.done) return
    result.value.then(data => {
      handleResult(g.next(data))
    }, err => {
      g.throw(err)
    })
  }

  handleResult(g.next())
}


co(main)

當(dāng)然這樣的執(zhí)行器在社區(qū)中已經(jīng)有一個(gè)比較完善的庫了co。這種co的方案在2015年之前是特別流行的,后來在出了async/await語法糖之后,這種方案相對來講就沒有那么普及了。使用generator這種方法最明顯的變化就是異步調(diào)用回歸到扁平化了

async/await

有了generator之后js異步編程基本上與同步代碼有類似的體驗(yàn)了,但是使用generator這種異步方案還需要自己手動去寫一個(gè)執(zhí)行器函數(shù),會比較麻煩。在ES2017的版本中新增了一個(gè)叫做async的函數(shù),它同樣提供了這種扁平化的編程體驗(yàn),并且是語言層面的標(biāo)準(zhǔn)的異步編程語法。其實(shí)async函數(shù)就是生成器函數(shù)更方便的語法糖,所以語法上給generator函數(shù)是類似的。

async function main() {
  try {
    const user1 = await ajax('/json1.json')
    console.log(user1)

    const user2 = await ajax('/json2.json')
    console.log(user2)

    const user3 = await ajax('/json3.json')
    console.log(user3)
  } catch (error) {
    console.log(error)
  }
}

main()

async 函數(shù)返回一個(gè)Promise對象,更利于對整體代碼控制

promise.then(() => {
  console.log('all completed')
}).catch(err => {
  console.log(err)
})

到此這篇關(guān)于JS異步編程之generator與async/await語法糖詳解的文章就介紹到這了,更多相關(guān)JS generator async/await內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript Cookie的讀取和寫入函數(shù)

    JavaScript Cookie的讀取和寫入函數(shù)

    Cookie的讀取和寫入實(shí)現(xiàn)函數(shù)。
    2009-12-12
  • JavaScript中的FileReader圖片預(yù)覽上傳功能實(shí)現(xiàn)代碼

    JavaScript中的FileReader圖片預(yù)覽上傳功能實(shí)現(xiàn)代碼

    本文通過實(shí)例代碼給大家介紹了js中的FileReader圖片預(yù)覽上傳功能,代碼分為html和js代碼兩部分,具體實(shí)現(xiàn)代碼大家參考下本文
    2017-07-07
  • 使用JS獲取頁面上的所有標(biāo)簽

    使用JS獲取頁面上的所有標(biāo)簽

    這篇文章主要介紹了使用JS獲取頁面上的所有標(biāo)簽 ,需要的朋友可以參考下
    2018-10-10
  • JavaScript 裝逼指南(js另類寫法)

    JavaScript 裝逼指南(js另類寫法)

    如何寫JavaScript才能逼格更高呢?怎樣才能、讓別人一眼看出你不簡單呢?是否很期待別人在看完你的代碼之后感嘆一句原來還可以這樣寫呢?下面列出一些在JavaScript時(shí)的裝逼技巧,也可說是非常實(shí)用的寫法
    2020-05-05
  • CKeditor4 字體顏色功能配置方法教程

    CKeditor4 字體顏色功能配置方法教程

    這篇文章主要介紹了CKeditor4 字體顏色功能配置方法,結(jié)合圖文與實(shí)例的形式分析了CKeditor4 添加字體顏色擴(kuò)展功能的相關(guān)實(shí)現(xiàn)步驟與操作技巧,需要的朋友可以參考下
    2019-06-06
  • js 計(jì)數(shù)排序的實(shí)現(xiàn)示例(升級版)

    js 計(jì)數(shù)排序的實(shí)現(xiàn)示例(升級版)

    這篇文章主要介紹了js 計(jì)數(shù)排序的實(shí)現(xiàn)示例(升級版),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • JS Common 2 之比較常用到的函數(shù)

    JS Common 2 之比較常用到的函數(shù)

    JS Common 2 之比較常用到的函數(shù)...
    2007-03-03
  • axios基本入門用法教程

    axios基本入門用法教程

    之前當(dāng)vue更新到2.0之后,作者就宣告不再對vue-resource更新,而是推薦的axios,前一段時(shí)間用了一下,現(xiàn)在說一下它的基本用法。文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-03-03
  • 一文搞懂JSON(JavaScript Object Notation)

    一文搞懂JSON(JavaScript Object Notation)

    Json 有兩種基本的結(jié)構(gòu),即 Json對象 和 Json 數(shù)組。通過 Json 對象和 Json 數(shù)組這兩種結(jié)構(gòu)的組合可以表示各種復(fù)雜的結(jié)構(gòu),今天通過本文給大家介紹JavaScript Object Notation的基本知識,感興趣的朋友一起看看吧
    2021-10-10
  • 微信小程序之間的參數(shù)傳遞、獲取的操作方法

    微信小程序之間的參數(shù)傳遞、獲取的操作方法

    這篇文章主要介紹了微信小程序中如何獲取和傳遞參數(shù),包括獲取當(dāng)前頁面參數(shù)、單獨(dú)input文本框參數(shù)的獲取、表單獲取參數(shù)信息、點(diǎn)擊表格單元格信息獲取行ID以及前端頁面跳轉(zhuǎn)傳遞多個(gè)參數(shù)等,感興趣的朋友跟隨小編一起看看吧
    2025-01-01

最新評論

东乡县| 乐安县| 阿克陶县| 蓬溪县| 万全县| 金华市| 赞皇县| 呼图壁县| 陵水| 定兴县| 石家庄市| 朝阳市| 济阳县| 县级市| 巴马| 静海县| 留坝县| 台北县| 房产| 民勤县| 泊头市| 长宁县| 钦州市| 古田县| 深水埗区| 庄浪县| 焦作市| 渑池县| 绥棱县| 平凉市| 旌德县| 塔河县| 凤翔县| 湘阴县| 包头市| 阳山县| 定襄县| 龙门县| 陇西县| 东宁县| 田林县|