{"id":18402083,"url":"https://github.com/khrj/p-queue","last_synced_at":"2026-03-09T03:35:21.493Z","repository":{"id":51171807,"uuid":"337100731","full_name":"khrj/p-queue","owner":"khrj","description":"Promise queue with concurrency control, for Deno","archived":false,"fork":false,"pushed_at":"2023-08-13T01:45:20.000Z","size":102,"stargazers_count":22,"open_issues_count":4,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-12T22:57:52.184Z","etag":null,"topics":["api","concurrency","deno","module","port","promise","queue","rate-limits","typescript"],"latest_commit_sha":null,"homepage":"https://deno.land/x/p_queue","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/khrj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-02-08T14:22:14.000Z","updated_at":"2025-11-05T04:05:49.000Z","dependencies_parsed_at":"2022-09-22T17:20:28.540Z","dependency_job_id":null,"html_url":"https://github.com/khrj/p-queue","commit_stats":{"total_commits":10,"total_committers":2,"mean_commits":5.0,"dds":0.09999999999999998,"last_synced_commit":"f0042a2e49e1261f921c70a20769bc436be9180f"},"previous_names":["khushrajrathod/pqueue"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/khrj/p-queue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khrj%2Fp-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khrj%2Fp-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khrj%2Fp-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khrj%2Fp-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/khrj","download_url":"https://codeload.github.com/khrj/p-queue/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khrj%2Fp-queue/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30281584,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T02:57:19.223Z","status":"ssl_error","status_checked_at":"2026-03-09T02:56:26.373Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","concurrency","deno","module","port","promise","queue","rate-limits","typescript"],"created_at":"2024-11-06T02:41:05.515Z","updated_at":"2026-03-09T03:35:21.463Z","avatar_url":"https://github.com/khrj.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"assets/logo.svg\" width=\"700\" height=\"500\" alt=\"People standing in queue illustration\"\u003e\n    \u003ch1\u003ePromise Queue\u003c/h1\u003e\n    \u003cp\u003e\n        \u003cb\u003ePromise queue with concurrency control. Deno port of \u003ca href=\"https://github.com/sindresorhus/p-queue\"\u003esindresorhus's p-queue for node\u003c/a\u003e\u003c/b\u003e\n    \u003c/p\u003e\n    \u003cp\u003e\n        \u003cimg alt=\"build status\" src=\"https://img.shields.io/github/workflow/status/khrj/p-queue/Deno?label=checks\" \u003e\n        \u003cimg alt=\"language\" src=\"https://img.shields.io/github/languages/top/khrj/p-queue\" \u003e\n        \u003cimg alt=\"code size\" src=\"https://img.shields.io/github/languages/code-size/khrj/p-queue\"\u003e\n        \u003cimg alt=\"issues\" src=\"https://img.shields.io/github/issues/khrj/p-queue\" \u003e\n        \u003cimg alt=\"license\" src=\"https://img.shields.io/github/license/khrj/p-queue\"\u003e\n        \u003cimg alt=\"version\" src=\"https://img.shields.io/github/v/release/khrj/p-queue\"\u003e\n    \u003c/p\u003e\n    \u003cp\u003e\n        \u003cb\u003e\u003ca href=\"https://deno.land/x/p_queue\"\u003eView on deno.land\u003c/a\u003e\u003c/b\u003e\n    \u003c/p\u003e\n    \u003cbr\u003e\n    \u003cbr\u003e\n    \u003cbr\u003e\n\u003c/div\u003e\n\nUseful for rate-limiting async (or sync) operations. For example, when interacting with a REST API or when doing CPU/memory intensive tasks.\n\n## Usage\n\nHere we run only one promise at the time. For example, set `concurrency` to 4 to run four promises at the same time.\n\n```js\nimport PQueue from \"https://deno.land/x/p_queue@1.0.1/mod.ts\"\n\nconst queue = new PQueue({\n    concurrency: 1,\n})\n\nasync function one() {\n    await queue.add(() =\u003e fetch(\"https://sindresorhus.com\"))\n    console.log(\"Done: sindresorhus.com\")\n}\n\nasync function two() {\n    await queue.add(() =\u003e fetch(\"https://avajs.dev\"))\n    console.log(\"Done: avajs.dev\")\n}\n\nasync function three() {\n    const task = await getUnicornTask()\n    await queue.add(task)\n    console.log(\"Done: Unicorn task\")\n}\n\none()\ntwo()\nthree()\n```\n\n## API\n\nSee https://doc.deno.land/https/deno.land/x/p_queue@1.0.1/mod.ts\n\n## Events\n\n### active\n\nEmitted as each item is processed in the queue for the purpose of tracking progress.\n\n```js\nimport PQueue from \"https://deno.land/x/p_queue@1.0.1/mod.ts\"\nconst delay = (ms: number) =\u003e new Promise(r =\u003e setTimeout(r, ms))\n\nconst queue = new PQueue({\n    concurrency: 2,\n})\n\nlet count = 0\nqueue.on(\"active\", () =\u003e {\n    console.log(\n        `Working on item #${++count}.  Size: ${queue.size}  Pending: ${queue.pending}`,\n    )\n})\n\nqueue.add(() =\u003e Promise.resolve())\nqueue.add(() =\u003e delay(2000))\nqueue.add(() =\u003e Promise.resolve())\nqueue.add(() =\u003e Promise.resolve())\nqueue.add(() =\u003e delay(500))\n```\n\n### idle\n\nEmitted every time the queue becomes empty and all promises have completed `queue.size === 0 \u0026\u0026 queue.pending === 0` .\n\n```js\nimport PQueue from \"https://deno.land/x/p_queue@1.0.1/mod.ts\"\nconst delay = (ms: number) =\u003e new Promise(r =\u003e setTimeout(r, ms))\n\nconst queue = new PQueue()\n\nqueue.on(\"idle\", () =\u003e {\n    console.log(\n        `Queue is idle.  Size: ${queue.size}  Pending: ${queue.pending}`,\n    )\n})\n\nconst job1 = queue.add(() =\u003e delay(2000))\nconst job2 = queue.add(() =\u003e delay(500))\n\nawait job1\nawait job2\n// =\u003e 'Queue is idle.  Size: 0  Pending: 0'\n\nawait queue.add(() =\u003e delay(600))\n// =\u003e 'Queue is idle.  Size: 0  Pending: 0'\n```\n\nThe `idle` event is emitted every time the queue reaches an idle state. On the other hand, the promise the `onIdle()` function returns resolves once the queue becomes idle instead of every time the queue is idle.\n\n### add\n\nEmitted every time the add method is called and the number of pending or queued tasks is increased.\n\n### next\n\nEmitted every time a task is completed and the number of pending or queued tasks is decreased.\n\n```js\nimport PQueue from \"https://deno.land/x/p_queue@1.0.1/mod.ts\"\nconst delay = (ms: number) =\u003e new Promise(r =\u003e setTimeout(r, ms))\n\nconst queue = new PQueue()\n\nqueue.on(\"add\", () =\u003e {\n    console.log(\n        `Task is added.  Size: ${queue.size}  Pending: ${queue.pending}`,\n    )\n})\nqueue.on(\"next\", () =\u003e {\n    console.log(\n        `Task is completed.  Size: ${queue.size}  Pending: ${queue.pending}`,\n    )\n})\n\nconst job1 = queue.add(() =\u003e delay(2000))\nconst job2 = queue.add(() =\u003e delay(500))\n\nawait job1\nawait job2\n// =\u003e 'Task is added.  Size: 0  Pending: 1'\n// =\u003e 'Task is added.  Size: 0  Pending: 2'\n\nawait queue.add(() =\u003e delay(600))\n// =\u003e 'Task is completed.  Size: 0  Pending: 1'\n// =\u003e 'Task is completed.  Size: 0  Pending: 0'\n```\n\n## Advanced example\n\nA more advanced example to help you understand the flow.\n\n```js\nimport PQueue from \"https://deno.land/x/p_queue@1.0.1/mod.ts\"\nconst delay = (ms: number) =\u003e new Promise(r =\u003e setTimeout(r, ms))\n\nconst queue = new PQueue({\n    concurrency: 1,\n})\n\nasync function taskOne() {\n    await delay(200)\n\n    console.log(`8. Pending promises: ${queue.pending}`)(// =\u003e '8. Pending promises: 0'\n\n    async () =\u003e {\n        await queue.add(async () =\u003e \"🐙\")\n        console.log(\"11. Resolved\")\n    })()\n\n    console.log(\"9. Added 🐙\")\n\n    console.log(`10. Pending promises: ${queue.pending}`)\n    // =\u003e '10. Pending promises: 1'\n\n    await queue.onIdle()\n    console.log(\"12. All work is done\")\n}\n\nasync function taskTwo() {\n    await queue.add(async () =\u003e \"🦄\")\n    console.log(\"5. Resolved\")\n}\n\nconsole.log(\"1. Added 🦄\")\n;(async () =\u003e {\n    await queue.add(async () =\u003e \"🐴\")\n    console.log(\"6. Resolved\")\n})()\nconsole.log(\"2. Added 🐴\")\n;(async () =\u003e {\n    await queue.onEmpty()\n    console.log(\"7. Queue is empty\")\n})()\n\nconsole.log(`3. Queue size: ${queue.size}`)\n// =\u003e '3. Queue size: 1`\n\nconsole.log(`4. Pending promises: ${queue.pending}`)\n// =\u003e '4. Pending promises: 1'\n```\n\n```\n$ deno run -A test.ts\n\n01. Added 🦄\n02. Added 🐴\n03. Queue size: 1\n04. Pending promises: 1\n05. Resolved 🦄\n06. Resolved 🐴\n07. Queue is empty\n08. Pending promises: 0\n09. Added 🐙\n10. Pending promises: 1\n11. Resolved 🐙\n12. All work is done\n```\n\n## Custom QueueClass\n\nFor implementing more complex scheduling policies, you can provide a QueueClass in the options:\n\n```js\nclass QueueClass {\n    constructor() {\n        this._queue = []\n    }\n\n    enqueue(run, options) {\n        this._queue.push(run)\n    }\n\n    dequeue() {\n        return this._queue.shift()\n    }\n\n    get size() {\n        return this._queue.length\n    }\n\n    filter(options) {\n        return this._queue\n    }\n}\n\nconst queue = new PQueue({\n    queueClass: QueueClass,\n})\n```\n\n`p_queue` will call corresponding methods to put and get operations from this queue.\n\n## FAQ\n\n#### How do the `concurrency` and `intervalCap` options affect each other?\n\nThey are just different constraints. The `concurrency` option limits how many things run at the same time. The `intervalCap` option limits how many things run in total during the interval (over time).\n\n## Supporters\n\n- HUGE thanks to @sindresorhus -- this repository is mostly his code, modified to work with Deno\n\n[![Stargazers repo roster for @khrj/p-queue](https://reporoster.com/stars/khrj/p-queue)](https://github.com/khrj/p-queue/stargazers)\n\n[![Forkers repo roster for @khrj/p-queue](https://reporoster.com/forks/khrj/p-queue)](https://github.com/khrj/p-queue/network/members)\n\n## Related\n\n- [p-timeout](https://github.com/khrj/p-timeout)\n- [p-retried](https://github.com/khrj/p-retried)\n- [retried](https://github.com/khrj/retried)\n- [...more](https://github.com/khrj/deno-modules)\n\n## License\n\n- P(romise) Queue is licensed under the MIT license.\n- Code is adapted from Sindre's [p-queue for node](https://github.com/sindresorhus/p-queue) (also under the MIT license)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhrj%2Fp-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkhrj%2Fp-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhrj%2Fp-queue/lists"}