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

javascript generator生成器函數(shù)與asnyc/await語法糖

 更新時間:2023年03月24日 16:47:11   作者:開水泡飯520  
本文主要介紹了javascript generator生成器函數(shù)與asnyc/await語法糖,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

Generator 異步方案

相比于傳統(tǒng)回調(diào)函數(shù)的方式處理異步調(diào)用,Promise最大的優(yōu)勢就是可以鏈式調(diào)用解決回調(diào)嵌套的問題。但是這樣寫依然會有大量的回調(diào)函數(shù),雖然他們之間沒有嵌套,但是還是沒有達到傳統(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ù)名之前,有一個“*”作為生成器函數(shù)的標示符。

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

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

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

const generator = foo()

const result = generator.next()

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

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方法,這個方法會給生成器函數(shù)內(nèi)部拋出一個異常

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

const generator = foo()

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

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

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

function ajax(url) {
? return new Promise((resove, reject) => {
? ? var xhr = new XMLHttpRequest()
? ? xhr.open('GET', url)
? ? // 新方法可以直接接受一個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)用其實都是差不多的,所以我們可以寫一個比較通用的執(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)

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

async/await

有了generator之后js異步編程基本上與同步代碼有類似的體驗了,但是使用generator這種異步方案還需要自己手動去寫一個執(zhí)行器函數(shù),會比較麻煩。在ES2017的版本中新增了一個叫做async的函數(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ù)返回一個Promise對象,更利于對整體代碼控制

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

到此這篇關于generator(生成器函數(shù))與asnyc/await的文章就介紹到這了,更多相關異步編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • JS組件系列之Bootstrap Icon圖標選擇組件

    JS組件系列之Bootstrap Icon圖標選擇組件

    這篇文章給大家介紹js組件系列之Bootstrap Icon圖標選擇組件,對bootstrap icon圖標相關知識感興趣的朋友一起學習吧
    2016-01-01
  • javascript給span標簽賦值的方法

    javascript給span標簽賦值的方法

    本篇文章通過兩種方法給大家介紹js給span標簽賦值的方法,兩種方法都比較不錯,特此分享給大家,供大家學習
    2015-11-11
  • js實現(xiàn)彈窗居中的簡單實例

    js實現(xiàn)彈窗居中的簡單實例

    下面小編就為大家?guī)硪黄猨s實現(xiàn)彈窗居中的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • JS 中 reduce()方法使用小結(jié)

    JS 中 reduce()方法使用小結(jié)

    reduce是一個對數(shù)組累積操作的方法,使用時要加上 return 返回累積操作的數(shù)據(jù),這樣 prev 才能獲取上一次執(zhí)行的結(jié)果,否則是 undefined,這篇文章主要介紹了JS 中 reduce()方法及使用詳解,需要的朋友可以參考下
    2023-12-12
  • javascript禁制后退鍵(Backspace)實例代碼

    javascript禁制后退鍵(Backspace)實例代碼

    這篇文章介紹了javascript禁制后退鍵(Backspace)實例代碼,有需要的朋友可以參考一下
    2013-11-11
  • JS前向后瞻正則表達式定義與用法示例

    JS前向后瞻正則表達式定義與用法示例

    這篇文章主要介紹了JS前向后瞻正則表達式定義與用法,分析了前向后瞻正則表達式的具體定義、功能及具體使用技巧,需要的朋友可以參考下
    2016-12-12
  • JavaScript實現(xiàn)簡單的Markdown語法解析器

    JavaScript實現(xiàn)簡單的Markdown語法解析器

    Markdown 是一種輕量級標記語言, 它允許人們使用易讀易寫的純文本格式編寫文檔,然后轉(zhuǎn)換成有效的 XHTML(或者HTML)文檔。本文將利用JavaScript實現(xiàn)簡單的Markdown語法解析器,感興趣的可以了解一下
    2023-03-03
  • 圖片懶加載imgLazyLoading.js使用詳解

    圖片懶加載imgLazyLoading.js使用詳解

    這篇文章主要為大家詳細介紹了圖片懶加載imgLazyLoading.js的使用方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • webpack里使用jquery.mCustomScrollbar插件的方法

    webpack里使用jquery.mCustomScrollbar插件的方法

    malihu-custom-scrollbar-plugin是一個依賴jquery的自定義網(wǎng)頁滾動條樣式插件,這篇文章主要介紹了webpack里使用jquery.mCustomScrollbar插件的方法,感興趣的小伙伴們可以參考一下
    2018-05-05
  • javascript如何實現(xiàn)create方法

    javascript如何實現(xiàn)create方法

    這篇文章主要介紹了javascript如何實現(xiàn)create方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11

最新評論

夏河县| 邳州市| 绥宁县| 察隅县| 丽水市| 申扎县| 黑龙江省| 齐河县| 吉首市| 清镇市| 英德市| 沙洋县| 武宁县| 武乡县| 玉田县| 雅江县| 巴东县| 固安县| 绿春县| 武隆县| 灯塔市| 九龙坡区| 凤台县| 巴南区| 阿克陶县| 紫阳县| 晋江市| 桑日县| 金乡县| 长泰县| 泾川县| 大石桥市| 宁都县| 江口县| 车险| 包头市| 平湖市| 庆元县| 苍南县| 河间市| 雅安市|