使用Promise实现:限制异步操作的并发个数,并尽可能快的完成全部

var urls = [{ picSrc: '下载路径' }, { picSrc: '下载路径' }]
function loadImg(item) {
  return new Promise((resolve, reject) => {
    downloadFile(item.picSrc)
      .then((res) => {
        console.log(res) // Blob {size: 40077, type: 'application/x-download'}
        this.$set(item, 'picSrc', URL.createObjectURL(res))
      })
      .catch((error) => {
        reject(new Error('Could not load image at' + item))
      })
    resolve(item)
  })
}

function limitLoad(list, handler, limit) {
  let sequence = [].concat(list) // 复制urls
  // 这一步是为了初始化 promises 这个"容器"
  let promises = sequence.splice(0, limit).map((item, index) => {
    return handler(item).then(() => {
      // 返回下标是为了知道数组中是哪一项最先完成
      /** join 数组转化为字符串
       *  split 字符串转化为数组
       *  slice 截取不改变原数组
       *  splice
       */
      return index
    })
  })
  // 注意这里要将整个变量过程返回,这样得到的就是一个Promise,可以在外面链式调用
  return sequence
    .reduce((pCollect, item) => {
      return pCollect
        .then(() => {
          return Promise.race(promises) // 返回已经完成的下标
        })
        .then((fastestIndex) => {
          // 获取到已经完成的下标
          // 将"容器"内已经完成的那一项替换
          promises[fastestIndex] = handler(item).then(() => {
            return fastestIndex // 要继续将这个下标返回,以便下一次变量
          })
        })
        .catch((err) => {
          console.error(err)
        })
    }, Promise.resolve()) // 初始化传入
    .then(() => {
      // 最后三个用.all来调用
      return Promise.all(promises)
    })
}
limitLoad(list, loadImg, 3)
  .then((res) => {
    console.log('图片全部加载完毕')
    console.log(res)
  })
  .catch((err) => {
    console.error(err)
  })

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值