Skip to content

Instantly share code, notes, and snippets.

@yuzhouu
Last active July 28, 2022 09:39
Show Gist options
  • Save yuzhouu/f5a70309c682880952b479073c711600 to your computer and use it in GitHub Desktop.
Save yuzhouu/f5a70309c682880952b479073c711600 to your computer and use it in GitHub Desktop.
限制promise操作的并发数
/*
* 改自 https://github.com/sindresorhus/p-limit
*/
export function limitPromiseConcurrency<Result = any>(concurrency: number) {
type FnType = () => Promise<Result>
type ResolveFn = (r: Result) => void
type RejectFn = (r: any) => void
if (concurrency <= 0) {
throw new TypeError('concurrency must greater than 0')
}
const queue: any[] = []
let activeCount = 0
const next = () => {
activeCount--
const task = queue.shift()
task?.()
}
const run = async (fn: FnType, resolve: ResolveFn, reject: RejectFn) => {
activeCount++
const p = fn()
try {
const result = await p
resolve(result)
next()
} catch (err: any) {
// 出现错误时清空队列
queue.length = 0
reject(err)
}
}
const enqueue = (fn: FnType, resolve: ResolveFn, reject: RejectFn) => {
queue.push(run.bind(undefined, fn, resolve, reject))
;(async () => {
await Promise.resolve()
if (activeCount < concurrency && queue.length > 0) {
queue.shift()()
}
})()
}
const generator = (fn: FnType) =>
new Promise((resolve, reject) => {
enqueue(fn, resolve, reject)
})
return generator
}
const limit = limitPromiseConcurrency(2)
const tasks = []
tasks.push(limit( () => { async action } ))
Promise.all(tasks).then(res => {}).catch(error => {})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment