首頁  >  文章  >  web前端  >  JavaScript如何處理並行請求?四種方式淺析

JavaScript如何處理並行請求?四種方式淺析

青灯夜游
青灯夜游轉載
2021-07-27 10:53:222438瀏覽

本篇文章和大家看看JavaScript如何處理並行請求?介紹一下JS處理平行請求的四種方式,希望對大家有幫助!

JavaScript如何處理並行請求?四種方式淺析

需求

兩個非同步請求同時發出,兩個請求都會返回時再做處理

實作

這裡的方法只提供思路,只做請求成功處理

#方法一

使用Promise.all

const startTime = new Date().getTime()
function request(time) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(time)
    }, time)
  })
}
let request1 = request(3000)
let request2 = request(2000)
Promise.all([request1, request2]).then(res => {
  console.log(res, new Date() - startTime)	// [ 3000, 2000 ] 3001
})

方法二

自訂狀態,在回呼中判斷回傳狀態,待2個請求都有回傳值時再做處理

const startTime = new Date().getTime()
function request(time) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(time)
    }, time)
  })
}
let state = [undefined, undefined]
let request1 = request(3000)
let request2 = request(2000)
request1.then(res => {
  state[0] = res
  process()
})
request2.then(res => {
  state[1] = res
  process()
})
function process() {
  if (state[0] && state[1]) {
    console.log(state, new Date() - startTime) // [ 3000, 2000 ] 3001
  }
}

方法三

generator,yield

const startTime = new Date().getTime()
function ajax(time, cb) {
  setTimeout(() => cb(time), time)
}
function request(time) {
  ajax(time, data => {
    it.next(data);
  })
}
function* main() {
  let request1 = request(3000);
  let request2 = request(2000);
  let res1 = yield request1
  let res2 = yield request2
  console.log(res1, res2, new Date() - startTime) // 2000 3000 3001
}
let it = main();
it.next();

這個地方有點問題,因為request2耗時較短,會先返回,也就是先執行it.next(2000),導致res1獲得了request2的返回值若使用co函數,則不會存在這個問題,因為co是在promise.then函數中才執行it.next(),相當於it.next()是鍊式呼叫

generator使用co函數

const co = require('co')
const startTime = new Date().getTime()
function request (time) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(time)
    }, time)
  })
}
co(function* () {
  let request1 = request(3000);
  let request2 = request(2000);
  let res1 = yield request1
  let res2 = yield request2
  console.log(res1, res2, new Date() - startTime) // 3000 2000 3001
})

有了co函數,就不需要產生it和執行next方法了; co的原理其實也簡單,就是遞歸執行next,直到done為true; 如果next傳回的value是Promise,則在then函數中執行next,若不是Promise,直接執行next函數 下面是co函數的簡版手寫實作

function co(func) {
  let it = func()
  let t = it.next()
  next()
  
  function next() {
    if (t.done) return
    if (t.value instanceof Promise) {
      t.value.then(res => {
        t = it.next(res)
        next()
      })
    } else {
      t = it.next(t.value)
      next()
    }
  }
}

方法四

有了generator,很容易想到async/await,畢竟async/ await就是generator實現的

// setTimeout模拟异步请求,time为请求耗时
const startTime = new Date().getTime()
function request (time) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(time)
    }, time)
  })
}
(async function () {
  let request1 = request(3000)
  let request2 = request(2000)
  let res1 = await request1
  console.log(res1, new Date() - startTime)	// 3000 3001
  let res2 = await request2
  console.log(res2, new Date() - startTime) // 2000 3005
})()

更多程式相關知識,請造訪:程式設計影片! !

以上是JavaScript如何處理並行請求?四種方式淺析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:掘金--milugloomy。如有侵權,請聯絡admin@php.cn刪除