Sunny-117 / js-challenges

✨✨✨ Challenge your JavaScript programming limits step by step

Home Page:https://juejin.cn/column/7244788137410560055

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

设计一个函数,该函数的参数为可同时发送请求的大小,返回一个函数,该函数的参数为要请求的url。 实现的效果为,同时发送n个请求,当有请求返回后往请求队列里push新的请求,并输出刚刚结束的请求的返回值。

Sunny-117 opened this issue · comments

设计一个函数,该函数的参数为可同时发送请求的大小,返回一个函数,该函数的参数为要请求的url。 实现的效果为,同时发送n个请求,当有请求返回后往请求队列里push新的请求,并输出刚刚结束的请求的返回值。
commented

function scheduler(tasks, max) {
// 当前并发数
let count = 0;
// 阻塞队列
let queue = [];
async function add(task) {
if (count >= max) {
// 阻塞
await new Promise((resolve) => queue.push(resolve));
}
count++;

        task().then((data) => {
            count--;
            // 阻塞队列有无阻塞
            if (queue.length) queue.shift()();
        });
    }
    for (let i = 0; i < tasks.length; i++) {
        add(tasks[i]);
    }
}

思路仅供参考,每个request方法都支持promise回调,使用递归+队列,只考虑了成功态了

function scheduler(max) {
  const queue = []
  let run = 0

  return function(url) {
    queue.push(function() {
      // return fetch(url)
      return new Promise(res => {
        setTimeout(()=> {
          res(url)
        }, url)
      })
    })

    return new Promise(resolve => {
      execute()

      function execute() {
        if (run < max && queue.length) {
          const task = queue.shift()
          run++
          task().then((value)=> {
            resolve(value)
            console.log(value)
          }).finally(()=> {
            run--
            execute()
          })
        }
      }
    })
  }
}

const addToRequest = scheduler(2)
addToRequest(1000)
addToRequest(500)
addToRequest(400)
addToRequest(300)
addToRequest(100)

function scheduler(max) {
const queue = []
let count = 0

function getCall() {
    if (queue[0]) {
        const obj = queue.shift()
        step(obj.url, obj.cb)
    }
}

function step(url, cb) {
    if (count < max) {
        count++
        if (cb) {
            setTimeout(() => {
                count--
                cb(url)
                getCall()
            }, url);
        } else {
            return new Promise(resolve => {
                setTimeout(() => {
                    count--
                    resolve(url)
                    getCall()
                }, url);
            })
        }
    } else {
        return new Promise(resolve => {
            queue.push({
                url,
                cb: resolve
            })
        })
    }
}
return step

}
const request = scheduler(2)
request(1000).then(res => console.log(res))
request(2000).then(res => console.log(res))
request(3000).then(res => console.log(res))
request(1000).then(res => console.log(res))
request(4000).then(res => console.log(res))
// 1000 2000 1000 3000 4000