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

请实现一个函数 schedule 以限制最大并发任务数 #95

Open
AwesomeDevin opened this issue Sep 12, 2023 · 0 comments
Open

请实现一个函数 schedule 以限制最大并发任务数 #95

AwesomeDevin opened this issue Sep 12, 2023 · 0 comments

Comments

@AwesomeDevin
Copy link
Owner

针对fn1fn2fn3fn4实现一个异步并发队列函数schedule(n),保证以下输出:

  • n = 1时,输出结果(1,2,3,4)分别相距 2秒/3秒/4秒
  • n = 2时,输出结果(1,2,3,4)分别相距 1秒/2秒/2秒
  • n = 3时,输出结果(1,2,3,4)分别相距 1秒/1秒/2秒
  • n >= 4时,输出结果(1,2,3,4)分别相距 1秒/1秒/1秒

思路:

  1. 小于 n 任务为同步执行任务,大于 n 任务为异步执行任务
  2. 实现一个同步队列
  3. 实现一个异步队列
  4. 同步队列执行完成后取异步队列任务执行

实现如下:

const fn1 = ()=>new Promise((resolve)=>{
  setTimeout(()=>{
    resolve(1)
  },1000)
})
      
const fn2 = () => new Promise((resolve)=>{
  setTimeout(()=>{
    resolve(2)
  },2000)
})

const fn3 = () => new Promise((resolve)=>{
  setTimeout(()=>{
    resolve(3)
  },3000)
})

const fn4 = () => new Promise((resolve)=>{
  setTimeout(()=>{
    resolve(4)
  },4000)
})

function schedule(max){
  const queue = []
  const asyncQueue = []
  let count = 0
  let cur = null
  
  function push(fn){
    queue.push(fn)
  }
  
  function pop(){
    return queue.shift()
  }
  
  function execute(task){
    count++
    return task().then(res=>{
      count--
      const cur = asyncQueue.shift()
      const next = cur?.next
      const asyncResolve = cur?.resolve
      if(asyncResolve && next){
        next().then(res=>{
          asyncResolve(res)
        })
      }
      return res
    })
  }
  
  function next(){
    const cur = pop()
    return execute(cur)  
  }
  
  function run(){
    return count < max ? next() :  new Promise((resolve)=>{
      asyncQueue.push({
        next: next,
        resolve
      })
    })
  }
  
  return {
    push, run
  }
}

const sd = schedule(1)

sd.push(fn1)
sd.push(fn2)
sd.push(fn3)
sd.push(fn4)

sd.run().then(res=>{
  console.log(res, new Date().getSeconds())
})
sd.run().then(res=>{
  console.log(res, new Date().getSeconds())
})
sd.run().then(res=>{
  console.log(res, new Date().getSeconds())
})
sd.run().then(res=>{
  console.log(res, new Date().getSeconds())
})

运行:
n = 1时,输出结果(1,2,3,4)分别相距 2秒/3秒/4秒:
image.png

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

1 participant