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

一文詳解如何有效的處理Promise并發(fā)

 更新時間:2023年04月19日 10:17:57   作者:liangyue  
這篇文章主要為大家介紹如何有效的處理Promise并發(fā)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

如上圖所示的代碼,相信大家在平時的開發(fā)中肯定用到不少,我們可以進行優(yōu)化,使得只用短短一半的時間就可以完成。 在上面的函數(shù)中,我們等待用戶信息請求完成后再請求詳情信息。但這兩個函數(shù)之間并沒有任何關(guān)聯(lián),所以我們可以同時觸發(fā)兩個請求,并同時等待完成。那么,我們有多少種方式來實現(xiàn)呢?你真的可以處理好Promise的并發(fā)么?接下來,我們進入正題。

Promise.all

如何實現(xiàn)

Promise.all 大家應該是比較熟悉的,Promise.all方法接收一個promiseiterable類型,如果所有傳入的promise都變成完成狀態(tài),Promise.all返回的Promise異步的變?yōu)橥瓿伞H绻麄魅氲?code>promise中有一個失敗(rejected),Promise.all將失敗的結(jié)果給失敗狀態(tài)的回調(diào)函數(shù),而不管其他promise是否完成。 我們可以如下實現(xiàn)剛才的代碼

async function init() {
  const [user, info] = await Promise.all([
    getUser(),
    getInfo()
  ])
  console.log('init', user, info)
}

現(xiàn)在這種方式,如果我們之前每個請求都需要1秒,一共需要2秒,那么現(xiàn)在兩個同時執(zhí)行只需要1秒就完成了!但是這樣也有一個問題:我們并沒有考慮報錯問題。你可能會認為,這個很簡單,把代碼放在一個try...cahtch中不就可以了,就像這樣:

async function init() {
  try {
    const [user, info] = await Promise.all([
      getUser(),
      getInfo()
    ])
    console.log('init ==== ', user, info)
  } catch(err) {
    console.log('err', err);
  }
}

但是,這樣的話會有一個問題,就像這樣:

function getUser() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('user reject')
    }, 500);
  })
}
function getInfo() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('info reject')
    }, 1000);
  })
}
// 輸出 err user reject

由于getUser優(yōu)先完成并出現(xiàn)錯誤,此時觸發(fā)了catch,而當getInfo再次完成并出現(xiàn)錯誤時,將不會觸發(fā)catch。因為catch代碼已經(jīng)運行,函數(shù)已經(jīng)完成。 那么,要怎么做呢?接下來,我們就講講應該如何處理報錯問題。

如何處理報錯

解決方式是,給Promise.all中的每個函數(shù)加上catch,如下:

function handle(err) {
  console.log('err', err)
}
function onReject(err) {
  handle(err);
  return new Error(err);
}
async function init() {
  const [user, info] = await Promise.all([
    getUser().catch(onReject),
    getInfo().catch(onReject)
  ])
  console.log('init', user instanceof Error, info instanceof Error) // init true true
}

這樣,我們在onReject函數(shù)中處理錯誤,并返回這個錯誤。所以現(xiàn)在我們生成的userinfo要么是Error要么是我們期望的效果,而Error我們可以用instanceof檢查它。

Promise.allSettled

解決并發(fā)我們還可以使用 Promise.allSettled ,我們會得到一個包含每個Promise結(jié)果的值或錯誤信息。

如何實現(xiàn)

接下來,我們來使用一下,代碼如下:

async function init() {
  const [userStatus, infoStatus] = await Promise.allSettled([
    getUser(),
    getInfo()
  ])
  console.log('info', userStatus, infoStatus)
}

現(xiàn)在,我們可以得到這樣的數(shù)據(jù):

結(jié)果對象有3個屬性:

  • status: fulfilledrejected
  • value: 僅在statusfulfilled時出現(xiàn),為Promiseresolve返回的值
  • reason: 僅在statusrejected時出現(xiàn),為Promisereject時返回的值

因此,我們可以讀取到每個Promise的狀態(tài),并單獨處理每個錯誤而不會遺漏任何的信息。

最后兩個技巧

Promise.race

Promise.race方法可接受一個可迭代的promise返回一個promise,一旦迭代器中某個promise解決或拒絕,返回的promise就會resolvereject。

我們可以這樣實現(xiàn)一個簡單的超時功能,代碼如下:

function getUser() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('user resolve')
    }, 5100);
  })
}
async function init() {
  // Race to see which Promise completes first
  const racePromise = Promise.race([
    getUser(),
    new Promise((resolve, reject) =>
      // Time out after 5 seconds
      setTimeout(() => reject(new Error('Timeout')), 5000)
    )
  ])
  try {
    const result = await racePromise
    console.log('result', result)
  } catch (err) {
    console.log('err', err)
    // Timed out!
  }
}

注意,通常情況下,如果有超時,那么你需要盡量的取消未完成的待處理任務。

另外,最好還是處理所有promisereject

const racePromise = Promise.race([
    getUser().catch(onReject),
    // xxx
  ])

Promise.any

Promise.any 等待任何一個promise成功則為成功,只有全部的promise都被reject,才會返回reject。通常我們可以使用Promise.any來實現(xiàn),當一個promise先完成后,取消其他的promise,不過要注意的是,我們并不總是同時要處理多個數(shù)據(jù),只是因為我們可以做到,所以要謹慎的使用它。

通常,我們不想出現(xiàn)未被處理的reject,所以,我們應該這樣寫:

const anyPromise = Promise.any([
    getUser().catch(onReject),
    getInfo().catch(onReject)
])

總結(jié)

前面我們已經(jīng)介紹了在使用promise處理并發(fā)問題時,應該如何的處理promisereject。但是也需要注意:過度的并發(fā)會導致網(wǎng)絡抖動、磁盤抖動或其他問題,雖然可以,但并不是一定要這樣做,有時使用async await也可以使代碼更容易理解和維護,所以,在使用之前我們更需要考慮是否需要。

以上就是一文詳解如何有效的處理Promise并發(fā)的詳細內(nèi)容,更多關(guān)于有效處理Promise并發(fā)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Openlayers實現(xiàn)面積測量的方法

    Openlayers實現(xiàn)面積測量的方法

    在Openlayers中,長度和面積的測量均依賴ol/sphere模塊,長度通過getLength方法計算,面積則通過getArea方法,面積測量不是計算平面面積,而是基于球面,適用于多邊形和多多邊形集合,感興趣的朋友一起看看吧
    2024-11-11
  • JS實現(xiàn)重新加載當前頁面或者父頁面的幾種方法

    JS實現(xiàn)重新加載當前頁面或者父頁面的幾種方法

    本文介紹了JS實現(xiàn)重新加載當前頁面或者父頁面的幾種方法.需要的朋友可以參考下
    2016-11-11
  • BootStrap實現(xiàn)帶關(guān)閉按鈕功能

    BootStrap實現(xiàn)帶關(guān)閉按鈕功能

    這篇文章主要介紹了BootStrap實現(xiàn)帶關(guān)閉按鈕功能,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02
  • JavaScript實現(xiàn)清空(重置)文件類型INPUT元素值的方法

    JavaScript實現(xiàn)清空(重置)文件類型INPUT元素值的方法

    這篇文章主要介紹了JavaScript實現(xiàn)清空(重置)文件類型INPUT元素值的方法,結(jié)合實例形式分析了javascript清空input文本框的常用方法與實現(xiàn)技巧,需要的朋友可以參考下
    2016-11-11
  • JavaScript中數(shù)據(jù)類型轉(zhuǎn)換總結(jié)

    JavaScript中數(shù)據(jù)類型轉(zhuǎn)換總結(jié)

    在js中,數(shù)據(jù)類型轉(zhuǎn)換分為顯式數(shù)據(jù)類型轉(zhuǎn)換和隱式數(shù)據(jù)類型轉(zhuǎn)換。本文將對此進行介紹,具有一定的參考價值,需要的朋友一起來看下吧
    2016-12-12
  • 微信小程序自動化部署的全過程

    微信小程序自動化部署的全過程

    由于微信小程序需要在微信小程序助手上發(fā)布,比較麻煩,可以配置CI 自動化的發(fā)布,下面這篇文章主要給大家介紹了關(guān)于微信小程序自動化部署的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • document.createElement()用法

    document.createElement()用法

    document.createElement()是在對象中創(chuàng)建一個對象,要與appendChild() 或 insertBefore()方法聯(lián)合使用。其中,appendChild() 方法在節(jié)點的子節(jié)點列表末添加新的子節(jié)點
    2013-03-03
  • JS實現(xiàn)的視頻彈幕效果示例

    JS實現(xiàn)的視頻彈幕效果示例

    這篇文章主要介紹了JS實現(xiàn)的視頻彈幕效果,涉及javascript基于事件響應的頁面元素屬性動態(tài)操作相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2018-08-08
  • 早該知道的7個JavaScript技巧

    早該知道的7個JavaScript技巧

    早該知道的7個JavaScript技巧,有了這7個JavaScript技巧,事半功倍,感興趣的小伙伴們可以參考一下
    2016-06-06
  • 微信小程序自定義導航欄

    微信小程序自定義導航欄

    這篇文章主要為大家詳細介紹了微信小程序自定義導航欄,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12

最新評論

崇礼县| 扶风县| 五家渠市| 海阳市| 九寨沟县| 甘泉县| 杭锦后旗| 平遥县| 临江市| 木兰县| 嘉义市| 东丽区| 夹江县| 神农架林区| 梓潼县| 揭阳市| 祁门县| 兴化市| 依安县| 天门市| 博罗县| 闽清县| 武冈市| 隆尧县| 云南省| 历史| 新乡市| 吉首市| 凤台县| 山西省| 清水河县| 靖远县| 清苑县| 营口市| 鲁山县| 林西县| 阳春市| 视频| 佛冈县| 乌拉特前旗| 安福县|