Last active
July 28, 2022 09:39
-
-
Save yuzhouu/f5a70309c682880952b479073c711600 to your computer and use it in GitHub Desktop.
限制promise操作的并发数
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 改自 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