{"id":30141968,"url":"https://github.com/solzimer/promise-stream-queue","last_synced_at":"2025-08-11T05:21:18.118Z","repository":{"id":57331472,"uuid":"90982957","full_name":"solzimer/promise-stream-queue","owner":"solzimer","description":"Promise Stream. Queue promises and retrieve the resolved/rejected ones in the inserted order","archived":false,"fork":false,"pushed_at":"2020-03-04T12:03:26.000Z","size":21,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-09T13:39:33.575Z","etag":null,"topics":["async","javascript","promise","queue","stream","sync"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/solzimer.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}},"created_at":"2017-05-11T13:34:23.000Z","updated_at":"2020-03-04T12:03:28.000Z","dependencies_parsed_at":"2022-09-01T09:23:07.889Z","dependency_job_id":null,"html_url":"https://github.com/solzimer/promise-stream-queue","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/solzimer/promise-stream-queue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solzimer%2Fpromise-stream-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solzimer%2Fpromise-stream-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solzimer%2Fpromise-stream-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solzimer%2Fpromise-stream-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/solzimer","download_url":"https://codeload.github.com/solzimer/promise-stream-queue/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solzimer%2Fpromise-stream-queue/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269775476,"owners_count":24474002,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["async","javascript","promise","queue","stream","sync"],"created_at":"2025-08-11T05:21:17.329Z","updated_at":"2025-08-11T05:21:18.112Z","avatar_url":"https://github.com/solzimer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# promise-stream-queue\nPromise Stream. Queue promises and retrieve the resolved/rejected ones in the inserted order\n\nThis module is responsible for serializing promises, but allowing their asynchronous execution. Unlike other queues, where promises are executed\nserially, one after another, what this module does is insert promises in a\nqueue, in a certain order, **allowing its asynchronous execution, but making the output be in the same order in which they were inserted**. As soon as the promise in the head of the queue is resolved, it is released, moving on to the next.\n\nIn case of promises never resolved/rejected, the stream allows an execution\ntimeout that releases the promise from the queue.\n\nThis modules is compatible with any [A+ Promises](https://www.promisejs.org/) module.\n\n## Installation\n\n    npm install promise-stream-queue\n\n## Usage\n\nSupose we execute 10 asynchronous tasks:\n\n```javascript\nvar arr = [1,2,3,4,5,6,7,8,9,10];\nvar promises = arr.map(i=\u003e{\n\treturn new Promise((resolve,reject)=\u003e{\n\t\tsetTimeout(()=\u003e{\n\t\t\tresolve(\"Promise =\u003e \"+i);\n\t\t},Math.floor(Math.random(1000)));\n\t});\n});\n```\n\nThe above code creates 10 promises that are resolved at a random timeout of 1\nsecond.\n\nThen, we could wait for them to be resolved with [**Promise.all**](https://www.promisejs.org/api/), an then\niterate the results in the same order of the \"*promises*\" array\n\n```javascript\nPromise.all(promises).then(results=\u003e{\n\tresults.forEach(res=\u003econsole.log(res));\n});\n```\nThat's OK, but we had to wait for **all the promises to be resolved**. What\nif we need to iterate for the results as soon as the are available?\n\nWe could just simply get the head element of the array and wait for its resolution, an then move to the next.\n\n```javascript\nfunction iterate() {\n\tvar promise = promises.shift();\n\tpromise.then(res=\u003e{\n\t\t// Process response\n\t\tdoSomething(res);\n\t\t// Move to next\n\t\titerate();\n\t})\n}\n```\n\nHere, the problem is that the array of promises is fixed, and we can't take into acount problems as promises never resolved/reject, etc.. What whe want is\na continuous stream where promises are pushed, and then retrieved the results\nin the same order they where inserted.\n\n```javascript\nconst Stream = require(\"promise-stream-queue\");\n\n// Creates the stream with max execution of 5 secs per promise\nvar stream = new Stream(5000);\t// Execution timeout of 5000 ms\nvar i = 0;\n\nsetInterval(()=\u003e{\n\tstream.push(new Promise((resolve,reject)=\u003e{\n\t\tvar randomTimeout = Math.floor(Math.random()*1000);\n\t\tsetTimeout(()=\u003eresolve(\"Promise =\u003e \"+i),randomTimeout);\n\t}));\n});\n\nstream.forEach((err,res,ex)=\u003e{\n\tconsole.log(res);\n});\n```\n\nNow, the *stream.forEach* method will, asynchronously iterate an stream of\nordered promises. The iteration never ends as long as promises are being\npushed to the stream.\n\n## API\n### new Stream(timeout)\nCreates a new stream with a max execution of *timeout* millisecons per promise.\nIf a promise fails to be resolved/reject after this timeout, it is discarded and rejected with a *timeout* error.\n\n### stream.push(promise)\nPushes a promise to the stream.\n\n### stream.kill(promise)\nSearch and discards a previously promise from the stream. This doesn't remove\nit from the stream, but the promise will be immediately rejected with a *kill* error.\n\n### stream.close()\nCloses the stream. New pushed promises will be ignored, and\nthe stream will be marked as closed. The pending promises\nare still being processed.\n\n### stream.drain()\nDrains the stream. Rejects all the pending promises of the\nqueue.\n\n### stream.toArray()\nReturns a snapshot of the stream as an static array of promises.\n\n### stream.forEach(callback(err,res,ex))\nIterates infinitely and asynchronously over the stream.\n\n### stream.forEachSync(callback(err,res,ex,next))\nSame as before, but now, the *next* argument is a function that must be called in order to move to the next element. This is useful when we want to wait to the callback function to finish the process before move to the next promise.\n\n### stream.done(callback)\nThe callback function will be invoked when the stream is closed and empty. Useful when the stream has been closed and we want to\nknow when all promises have been processed\n\n### stream.toStream(options)\nReturns a full implementation of a nodejs [Duplex Stream](https://nodejs.org/api/stream.html#stream_duplex_and_transform_streams) (Writable and Readable stream). This stream is [Object Mode](https://nodejs.org/api/stream.html#stream_object_mode) by default, and can be passed an optional transform callback before piping to another stream.\n```javascript\nvar stream = new Stream().toStream({readableObjectMode:false});\n\nfunction trfn(data,callback) {\n\tcallback(JSON.stringify(data)+\"\\n\");\n}\n\n// Pipe stream to stdout\nstream.transform(trfn).pipe(process.stdout);\n\n// Write promise to stream\nstream.write(new Promise((resolve,reject)=\u003e{\n\tsetTimeout(()=\u003e{\n\t\tresolve({data:\"This is a json data object\"});\n\t},100);\n}));\n```\n\n## Events\n### resolve\nFired when the head promise is resolved\n```javascript\nstream.on(\"resolve\",res=\u003econsole.log(res));\n```\n\n### reject\nFired when the head promise is rejected\n```javascript\nstream.on(\"reject\",err=\u003econsole.log(err));\n```\n\n### catch\nFired when the head promise has thrown an error\n```javascript\nstream.on(\"catch\",ex=\u003econsole.log(ex));\n```\n\n### closed\nFired when the stream has been closed\n```javascript\nstream.on(\"closed\",()=\u003econsole.log('Closed'));\n```\n\n### done\nFired when the stream is closed and all promises has been processed\n```javascript\nstream.on(\"done\",()=\u003econsole.log('Done'));\n```\n\n## Examples\n* [Asynchronous stream iteration](https://github.com/solzimer/promise-stream-queue/blob/master/examples/async.js)\n* [Synchronous stream iteration](https://github.com/solzimer/promise-stream-queue/blob/master/examples/sync.js)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsolzimer%2Fpromise-stream-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsolzimer%2Fpromise-stream-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsolzimer%2Fpromise-stream-queue/lists"}