all,race

function promiseAll(pList) {
  return new Promise((resolve, reject) => {
    const results = []
    let count = 0
 
    for (let i = 0; i < pList.length; i++) {
      pList[i]
        .then(data => {
          results[i] = data
          count++
 
          if (count === pList.length) {
            resolve(results)
          }
        })
        .catch(err => {
          reject(err)
        })
    }
  })
}
 
function promiseRace(pList) {
  return new Promise((resolve, reject) => {
    const promiseLength = pList.length
    if (promiseLength === 0) {
      return resolve()
    } else {
      for (let i = 0; i < promiseLength; i++) {
        Promise.resolve(pList[i]).then(
          value => resolve(value),
          reason => reject(reason)
        )
      }
    }
  })
}

利用promise控制最大并发数

// 设置我们要执行的任务
function loadImg (url) {
  return new Promise((resolve, reject) => {
    console.log('----' + url.info + 'start!')
    setTimeout(() => {
      console.log(url.info + 'OK!!!')
      resolve()
    }, url.time);
  })
}
 
const urls = [{
        info: 'link1',
        time: 3000
    },
    {
        info: 'link2',
        time: 2000
    },
    {
        info: 'link3',
        time: 5000
    },
    {
        info: 'link4',
        time: 1000
    },
    {
        info: 'link5',
        time: 1200
    },
    {
        info: 'link6',
        time: 2000
    },
    {
        info: 'link7',
        time: 800
    },
    {
        info: 'link8',
        time: 3000
    },
]
 
function promiseLimit(arr, maxCount) {
    let current = 0;
    let pendingList = []
    for (let i = 0; i < arr.length; i++) {
        doSend(arr[i])
    }
 
    function doSend(item) {
        if (current < maxCount) {
            current++
            loadImg(item).then(() => {
                current--
                if (pendingList.length > 0) {
                    doSend(pendingList.shift())
                }
            })
        } else {
            pendingList.push(item)
        }
 
    }
}
promiseLimit(urls, 3)

在限制最大并发数的同时,任务优先级高的先执行

// 设置我们要执行的任务
function loadImg (url) {
  return new Promise((resolve, reject) => {
    console.log('----' + url.info + 'start!')
    setTimeout(() => {
      console.log(url.info + 'OK!!!')
      resolve()
    }, url.time);
  })
}
 
const urls = [
  {
    info: 'link1',
    time: 3000,
    priority: 1
  },
  {
    info: 'link2',
    time: 2000,
    priority: 1
  },
  {
    info: 'link3',
    time: 5000,
    priority: 2
  },
  {
    info: 'link4',
    time: 1000,
    priority: 1
  },
  {
    info: 'link5',
    time: 1200,
    priority: 1
  },
  {
    info: 'link6',
    time: 2000,
    priority: 5
  },
  {
    info: 'link7',
    time: 800,
    priority: 1
  },
  {
    info: 'link8',
    time: 3000,
    priority: 1
  }
]
 
class PromiseQueue {
  constructor (options = {}) {
    this.concurrency = options.concurrency || 1
    this.currentCount = 0
    this.pendingList = []
  }
  
  // 添加任务方法
  add (task) {
    this.pendingList.push(task)
    this.run()
  }
 
  run () {
    if (this.pendingList.length === 0) {
      return
    }
 
    if (this.currentCount === this.concurrency) {
      return
    }
    this.currentCount++
 
    // 获取优先级最高的任务
    const { fn } = this.pendingList.sort((a, b) => b.priority - a.priority).shift()
    const promise = fn()
    promise.then(this.completeOne.bind(this)).catch(this.completeOne.bind(this))
 
  }
 
  // 执行完成方法
  completeOne () {
    this.currentCount--
    this.run()
  }
}
 
const q = new PromiseQueue({
  concurrency: 3
})
 
const formatTask = (url) => {
  return {
    fn: () => loadImg(url),
    priority: url.priority
  }
}
 
urls.forEach(url => {
  q.add(formatTask(url))
})
 
const highPriorityTask = {
  priority: 10,
  info: 'high priority',
  time: 2000
}
 
q.add(formatTask(highPriorityTask))