异步等待async/await实现并发请求

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style></style>
  </head>
  <body>
    <script>
      var urls = [
        'https://www.kkkk1000.com/images/getImgData/懂法守法.jpg', // 错误地址
        'https://www.kkkk1000.com/images/getImgData/ggDF第三方.jpg', // 错误地址
        'https://www.kkkk1000.com/images/getImgData/很关键.jpg', // 错误地址
        'https://www.kkkk1000.com/images/getImgData/二交换机.jpg', // 错误地址
        'https://www.kkkk1000.com/images/getImgData/getImgDatadata.jpg',
        'https://www.kkkk1000.com/images/getImgData/gray.gif',
        'https://www.kkkk1000.com/images/getImgData/Particle.gif',
        'https://www.kkkk1000.com/images/getImgData/arithmetic.png',
        'https://www.kkkk1000.com/images/getImgData/arithmetic2.gif',
        'https://www.kkkk1000.com/images/getImgData/getImgDataError.jpg',
        'https://www.kkkk1000.com/images/getImgData/arithmetic.gif',
        'https://www.kkkk1000.com/images/wxQrCode2.png',
      ]
      // 扩大待下载图片的数据量
      for (i = 0; i < 7; i++) {
        urls.push(...urls)
      }

      // 纯函数---请求下载图片,返回promise对象,成功时resolve,失败时reject
      function loadImg(url) {
        return new Promise((resolve, reject) => {
          const img = new Image()
          img.onload = () => {
            resolve()
          }
          img.onerror = reject
          img.src = url
        })
      }

      // 同步下载图片
      async function syncLoadImg(urls) {
        let starTime = new Date()
        for (let crtUrl of urls) {
          try {
            await loadImg(crtUrl)
            console.log('本图片链接可下')
          } catch (e) {
            console.log('突突突突突突,图片不可下啊啊啊')
          }
        }
        let endTime = new Date()
        console.log('time', starTime, endTime)
      }
      // syncLoadImg(urls)

      /**
       * 并发下载图片,但并发数为limit,
       * 任何时候一张图片下载完成或下载失败时,立马发起一张图片下载请求,让并发数控制在limit个
       * @param {Array}--url--所有待下载图片集合
       * @param {Function}--handler--载图片函数
       * @param {Number}--limit--下载的并发数量
       */
      async function limitLoadImg(urls, handler, limit) {
        let starTime = new Date()
        let sequence = [...urls]

        // 并发请求队列
        let taskQuene = sequence.splice(0, limit).map(async (item, index) => {
          // 成功或失败时返回当前项在队列中的索引
          try {
            await handler(item)
            return index
          } catch (e) {
            return index
          }
        })

        for (const crtUrl of sequence) {
          // 获取最快改变状态项的索引
          let pIdx = await Promise.race(taskQuene)
          console.log('并发任务队列中改变项索引:', pIdx)
          // 将任务队列中状态改变项替换成新的下载请求
          taskQuene[pIdx] = new Promise(async (resolve, reject) => {
            // 成功或失败时返回当前项在队列中的索引
            try {
              await handler(crtUrl)
              resolve(pIdx)
            } catch (e) {
              resolve(pIdx)
            }
          })
        }
        let endTime = new Date()
        console.log(starTime, endTime)
      }
      // limitLoadImg(urls, loadImg, 6)
    </script>
  </body>
</html>


版权声明:本文为weixin_43752765原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>