乐趣区

关于面试:手写题实现一个批量请求函数-multiRequesturls-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)
})
退出移动版