10

【手写题】实现一个批量请求函数 multiRequest(urls, maxNum)

 3 years ago
source link: https://segmentfault.com/a/1190000040587870
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【手写题】实现一个批量请求函数 multiRequest(urls, maxNum)

  1. 要求最大并发数 maxNum
  2. 每当有一个请求返回,就留下一个空位,可以增加新的请求
  3. 所有请求完成后,结果按照 urls 里面的顺序依次打出
// 模拟请求
function request(url) {
  return new Promise((resolve) => {
    const time = Math.random() * 1000;
    setTimeout(() => resolve(url), time);
  });
}
async function multiRequest(urls, maxNum) {
  let data = urls.map((url, index) => ({ index, url })) // 因为最终要按照顺序输出,所以给每个url追加一个index属性,用于记录在数组中的位置,确保按序输出
  let result = [] // 存放结果的数组
  // 巧用Array.from, length是开辟的数组长度,这个可以控制最大的并发数量。后面回调方法用于存放异步请求的函数
  let promises = Array.from({ length: Math.min(maxNum,data.length) }, () => getChain(data, result))
  // 利用Promise.all并发执行异步函数
  await Promise.all(promises)
  // 通过函数参数接收最终的一个结果
  return result
}

async function getChain(data, res = []) {
  // 利用队列的思想,一个个pop出来执行,只要urls还有,就继续执行
  while (data.length) {
    let one = data.pop()
    try {
      let urlRes = await request(one.url)
      // 结果按照索引顺序存储
      res[one.index] = urlRes
    }
    catch (e) {
      res[one.index] = e
    }
  }
}
// 调用
const urls = ['www.example1.com', 'www.example2.com', 'www.example3.com', 'www.example4.com', 'www.example5.com']
multiRequest(urls, 5).then(finalRes => {
  console.log('done', finalRes)
})

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK