异步并发

76 阅读1分钟
function multiRequest(urls: any[], maxNum: number) {
  let urlsClone = [...urls];
  let result = new Array(urls.length);
  let isDoneArr = new Array(urls.length).fill(0);

  let queueLimt = Math.min(maxNum, urls.length);
  let queue: never[] | undefined = [];

  while (enqueue(queue, urls.shift()) < queueLimt) { }
  let promise = {
    resolve: '',
    reject: ''
  };

  function request(queue: never[] | undefined, url: any) {
    console.log('开始任务', url);
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('完成任务', url)
        let i = urlsClone.indexOf(url);
        result[i] = url;

        dequeue(queue, url);
        resolve(true);
      }, 1000 * Math.floor(Math.random() * 5 + 1));
    });
  }

  function dequeue(queue = [], url: any) {
    queue.splice(queue.indexOf(url), 1);
    if (urls.length) {
      enqueue(queue, urls.shift());
    } else {
      if (isDoneArr.indexOf(0) === -1) {
        promise.resolve(result);
      }
    }
  }

  function enqueue(queue = [], url: any) {
    let len = queue.push(url);
    request(queue, url);
    return len;
  }

  return new Promise((resolve, reject) => {
    return promise.resolve = resolve
  })
}

let logs = 'answerTime';
console.log(logs);
multiRequest([1, 2, 3, 4, 5, 6, 7, 8, 9], 5).then(res => {
  // console.timeLog(logs);
  console.log(res)
})

// vue3
let isDoneArr = ref();
const multiRequest = (requestDatas: any[], maxNum: number) => {
  let urlsClone = [...requestDatas];
  let result = new Array(requestDatas.length);
  
  isDoneArr.value = new Array(requestDatas.length).fill(0);
  let queueLimt = Math.min(maxNum, requestDatas.length);
  let queue: never[] | undefined = [];

  let promise = {
    resolve: '',
    reject: ''
  };

  const request = (queue: never[] | undefined, requestData: any) => {
    console.log('开始任务', requestData);
    return new Promise((resolve, reject) => {
      let data = new FormData();
      data.append("file", requestData);
      reqUpload(data).then(res => {
        if (res?.code === 200) {
          // resolve(res.data)
          console.log('完成任务')
          let i = urlsClone.findIndex(item => item.name === requestData.name)
          result[i] = requestData;

          dequeue(queue, requestData);
          resolve(true);
        }
      })
    });
  }

  const dequeue = (queue = [], requestData: any) => {
    // queue.splice(queue.indexOf(requestData), 1);
    queue.splice(queue.findIndex(item => item.name === requestData.name), 1);
    if (requestDatas.length) {
      enqueue(queue, requestDatas.shift());
    } else {
      if (isDoneArr.value.indexOf(0) === -1) {
        console.log('isDoneArr.indexOf(0) === -1')
        // promise.resolve(result);
      }
    }
  }

  const enqueue = (queue = [], url: any) => {
    let len = queue.push(url);
    request(queue, url);
    return len;
  }

  while (enqueue(queue, requestDatas.shift()) < queueLimt) { }
  

  return new Promise((resolve, reject) => {
    // resolve(result)
    return promise.resolve = resolve(111)
  })
}
class Scheduler {
  constructor(limit) {
    this.limit = limit;//最大限制
    this.queue = [];// 任务队列
    this.count = 0;// 计数器
  }

  addTask(timeout, task) {
    this.queue.push([timeout, task]);
  }

  start() {
    if (this.queue.length > 0 && this.count < this.limit) {
      this.count++;
      let [timeout, task] = this.queue.shift();
      setTimeout(() => {
        console.log("task content:", task);
        this.count--;
        this.start();
      }, timeout * 1000);
    }
    this.start();
  }
}