Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Sunny-117 opened this issue Nov 3, 2022 · 4 comments

Comments

@Sunny-117
Copy link
Owner

No description provided.

@coscsoc
Copy link

coscsoc commented Nov 7, 2022

这题就是异步并发控制吧
https://github.com/rxaviers/async-pool/blob/1.x/lib/es7.js

@cscty
Copy link

cscty commented Jun 19, 2023

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]);
    }
}

@tyust512
Copy link

思路仅供参考,每个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)

@gswysy
Copy link

gswysy commented Feb 23, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants