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

重學(xué) JS:為啥 await 不能用在 forEach 中詳解

 更新時(shí)間:2019年04月15日 17:11:02   作者:yck  
這篇文章主要介紹了重學(xué) JS:為啥 await 不能用在 forEach 中,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

這是重學(xué) JS 系列的第三篇文章,寫這個(gè)系列的初衷也是為了夯實(shí)自己的 JS 基礎(chǔ)或者了解一些之前不知道的東西。既然是重學(xué),肯定不會(huì)從零開(kāi)始介紹一個(gè)知識(shí)點(diǎn),如有遇到不會(huì)的內(nèi)容請(qǐng)自行查找資料。

不知道你有沒(méi)有寫過(guò)類似的代碼,反正以前我是寫過(guò)

function test() {
 let arr = [3, 2, 1]
 arr.forEach(async item => {
  const res = await fetch(item)
  console.log(res)
 })
 console.log('end')
}

function fetch(x) {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve(x)
  }, 500 * x)
 })
}

test()

我當(dāng)時(shí)期望的打印順序是

3
2
1
end

 結(jié)果現(xiàn)實(shí)與我開(kāi)了個(gè)玩笑,打印順序居然是

end
1
2
3

為什么?

其實(shí)原因很簡(jiǎn)單,那就是 forEach 只支持同步代碼。

我們可以參考下 Polyfill 版本的 forEach,簡(jiǎn)化以后類似就是這樣的偽代碼

while (index < arr.length) {
  // 也就是我們傳入的回調(diào)函數(shù)
  callback(item, index)
}

從上述代碼中我們可以發(fā)現(xiàn),forEach 只是簡(jiǎn)單的執(zhí)行了下回調(diào)函數(shù)而已,并不會(huì)去處理異步的情況。并且你在 callback 中即使使用 break 也并不能結(jié)束遍歷。

怎么解決?

一般來(lái)說(shuō)解決的辦法有兩種。

第一種是使用 Promise.all 的方式

async function test() {
 let arr = [3, 2, 1]
 await Promise.all(
  arr.map(async item => {
   const res = await fetch(item)
   console.log(res)
  })
 )
 console.log('end')
}

這樣可以生效的原因是 async 函數(shù)肯定會(huì)返回一個(gè) Promise 對(duì)象,調(diào)用 map 以后返回值就是一個(gè)存放了 Promise 的數(shù)組了,這樣我們把數(shù)組傳入 Promise.all 中就可以解決問(wèn)題了。但是這種方式其實(shí)并不能達(dá)成我們要的效果,如果你希望內(nèi)部的 fetch 是順序完成的,可以選擇第二種方式。

第一種方法是使用 for...of

async function test() {
 let arr = [3, 2, 1]
 for (const item of arr) {
  const res = await fetch(item)
  console.log(res)
 }
 console.log('end')
}

這種方式相比 Promise.all 要簡(jiǎn)潔的多,并且也可以實(shí)現(xiàn)開(kāi)頭我想要的輸出順序。

但是這時(shí)候你是否又多了一個(gè)疑問(wèn)?為啥 for...of 內(nèi)部就能讓 await 生效呢。

因?yàn)?for...of 內(nèi)部處理的機(jī)制和 forEach 不同,forEach 是直接調(diào)用回調(diào)函數(shù),for...of 是通過(guò)迭代器的方式去遍歷。

async function test() {
 let arr = [3, 2, 1]
 const iterator = arr[Symbol.iterator]()
 let res = iterator.next()
 while (!res.done) {
  const value = res.value
  const res1 = await fetch(value)
  console.log(res1)
  res = iterator.next()
 }
 console.log('end')
}

最后
以上就是本篇文章的全部?jī)?nèi)容了,如果你還有什么疑問(wèn)歡迎在評(píng)論區(qū)與我互動(dòng)。

我所有的系列文章都會(huì)在我的 Github 中最先更新,有興趣的可以關(guān)注下。今年主要會(huì)著重寫以下三個(gè)專欄

重學(xué) JS
React 進(jìn)階
重寫組件

以上所述是小編給大家介紹的為啥await 不能用在 forEach 中詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Js獲取事件對(duì)象代碼

    Js獲取事件對(duì)象代碼

    js下比較實(shí)用的事件綁定代碼,學(xué)習(xí)js 的朋友一定要學(xué)習(xí)的,為你的頁(yè)面增加更好的交互。
    2010-08-08
  • 微信小程序?qū)崿F(xiàn)頂部下拉菜單欄

    微信小程序?qū)崿F(xiàn)頂部下拉菜單欄

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)頂部下拉菜單欄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • 淺談JavaScript超時(shí)調(diào)用和間歇調(diào)用

    淺談JavaScript超時(shí)調(diào)用和間歇調(diào)用

    JavaScript是單線程語(yǔ)言,但它允許通過(guò)設(shè)置超時(shí)值和間歇時(shí)間值來(lái)調(diào)度代碼在特定的時(shí)刻執(zhí)行。前者是在指定的時(shí)間過(guò)后執(zhí)行代碼,而后者則是每隔指定的時(shí)間就執(zhí)行一次代碼。
    2015-08-08
  • js中hasOwnProperty()方法詳解

    js中hasOwnProperty()方法詳解

    本文主要介紹了js中hasOwnProperty()方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 小程序?qū)崿F(xiàn)圖片預(yù)覽裁剪插件

    小程序?qū)崿F(xiàn)圖片預(yù)覽裁剪插件

    這篇文章主要為大家詳細(xì)介紹了小程序?qū)崿F(xiàn)圖片預(yù)覽裁剪插件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • JS非行間樣式獲取函數(shù)的實(shí)例代碼

    JS非行間樣式獲取函數(shù)的實(shí)例代碼

    這篇文章主要介紹了JS非行間樣式獲取函數(shù)的實(shí)現(xiàn)代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-06-06
  • 微信小程序?qū)崿F(xiàn)彈出菜單動(dòng)畫

    微信小程序?qū)崿F(xiàn)彈出菜單動(dòng)畫

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)彈出菜單動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • ES6中箭頭函數(shù)的定義與調(diào)用方式詳解

    ES6中箭頭函數(shù)的定義與調(diào)用方式詳解

    這篇文章主要給大家介紹了關(guān)于ES6中箭頭函數(shù)的定義與調(diào)用方式的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),相信會(huì)對(duì)大家的學(xué)習(xí)或者工作帶來(lái)一定的幫助,需要的朋友們下面來(lái)一起看看吧。
    2017-06-06
  • Javascript 實(shí)現(xiàn)匿名遞歸的實(shí)例代碼

    Javascript 實(shí)現(xiàn)匿名遞歸的實(shí)例代碼

    本篇文章主要介紹了Javascript 實(shí)現(xiàn)匿名遞歸的實(shí)例代碼,利用 arguments.callee 來(lái)實(shí)現(xiàn)匿名遞歸的方式。有興趣的可以了解一下
    2017-05-05
  • JavaScript this關(guān)鍵字的深入詳解

    JavaScript this關(guān)鍵字的深入詳解

    這篇文章主要給大家介紹了關(guān)于JavaScript this關(guān)鍵字的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01

最新評(píng)論

资溪县| 绵阳市| 石嘴山市| 青川县| 离岛区| 千阳县| 铁岭县| 临沭县| 甘谷县| 横峰县| 治多县| 康平县| 南皮县| 邮箱| 洪湖市| 尼玛县| 虞城县| 佳木斯市| 平舆县| 南澳县| 错那县| 邛崃市| 晋城| 明水县| 新兴县| 凌源市| 大新县| 建德市| 普兰县| 通江县| 兰坪| 吉林市| 泾川县| 莆田市| 吉林省| 子长县| 海兴县| 连江县| 东源县| 陕西省| 东丰县|