Title: Make stream internal methods support promises / async await · Issue #31387 · nodejs/node · GitHub
Open Graph Title: Make stream internal methods support promises / async await · Issue #31387 · nodejs/node
X Title: Make stream internal methods support promises / async await · Issue #31387 · nodejs/node
Description: Hello all, It would be great if streams internal methods such as _write, _transform would support also a promise based implementation. To clarify what I mean, here's an example. Classic implementation of a writable streams that receives ...
Open Graph Description: Hello all, It would be great if streams internal methods such as _write, _transform would support also a promise based implementation. To clarify what I mean, here's an example. Classic implementat...
X Description: Hello all, It would be great if streams internal methods such as _write, _transform would support also a promise based implementation. To clarify what I mean, here's an example. Classic impleme...
Opengraph URL: https://github.com/nodejs/node/issues/31387
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Make stream internal methods support promises / async await","articleBody":"Hello all,\r\nIt would be great if streams internal methods such as `_write`, `_transform` would support also a promise based implementation.\r\n\r\nTo clarify what I mean, here's an example.\r\n\r\nClassic implementation of a writable streams that receives objects containing a `path` and a `content` and it will write a file with such content for every received chunk.\r\n\r\n## Classic implementation\r\n\r\n```javascript\r\nimport { Writable } from 'stream'\r\nimport { promises as fs } from 'fs'\r\nimport { dirname } from 'path'\r\nimport mkdirp from 'mkdirp'\r\n\r\nexport class ToFileStream extends Writable {\r\n constructor (opts) {\r\n super({ ...opts, objectMode: true })\r\n }\r\n\r\n async _write (chunk, encoding, cb) {\r\n mkdirp(dirname(chunk.path), (err) =\u003e {\r\n if (err) {\r\n return cb(err)\r\n }\r\n\r\n fs.writeFile(chunk.path, chunk.content, cb)\r\n })\r\n }\r\n}\r\n```\r\n\r\nNice and standard, but as it happens with callback-based APIs, it's easy to end up with a callback hell situation and repeated code in case of conditional asynchronous work.\r\n\r\n## Desired implementation\r\n\r\n**This does not work as of today**\r\n\r\n```javascript\r\nimport { Writable } from 'stream'\r\nimport { promises as fs } from 'fs'\r\nimport { dirname } from 'path'\r\nimport mkdirp from 'mkdirp-promise'\r\n\r\nexport class ToFileStream extends Writable {\r\n constructor (opts) {\r\n super({ ...opts, objectMode: true })\r\n }\r\n\r\n async _write (chunk, encoding) {\r\n await mkdirp(dirname(chunk.path))\r\n return fs.writeFile(chunk.path, chunk.content)\r\n }\r\n}\r\n```\r\n\r\nThis would feel quite clean and standard for those used to the `async` `await` style\r\n\r\n## What we can do today\r\n\r\n```javascript\r\nimport { Writable } from 'stream'\r\nimport { promises as fs } from 'fs'\r\nimport { dirname } from 'path'\r\nimport mkdirp from 'mkdirp-promise'\r\n\r\nexport class ToFileStream extends Writable {\r\n constructor (opts) {\r\n super({ ...opts, objectMode: true })\r\n }\r\n\r\n async _write (chunk, encoding, cb) {\r\n try {\r\n await mkdirp(dirname(chunk.path))\r\n await fs.writeFile(chunk.path, chunk.content)\r\n cb()\r\n } catch (err) {\r\n cb(err)\r\n }\r\n }\r\n}\r\n```\r\n\r\nIn a situation with a lot of callbacks this might help to remove the nesting, but it still feels weird to (and hard to read) to mix `async` `await` style with callbacks.\r\n\r\n---\r\n\r\nWhat do you think? Would this be something feasible without breaking existing streams implementations?","author":{"url":"https://github.com/lmammino","@type":"Person","name":"lmammino"},"datePublished":"2020-01-16T20:38:59.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":9},"url":"https://github.com/31387/node/issues/31387"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:79c92555-da20-6ea9-cd8f-555ec306a1cd |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | C7EA:3EE845:255781C:332A58C:6A4ED6C0 |
| html-safe-nonce | 1ef985a1e056c0b9060e15ea294f915e98282e1db86c79296eef616ff14bc12b |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDN0VBOjNFRTg0NToyNTU3ODFDOjMzMkE1OEM6NkE0RUQ2QzAiLCJ2aXNpdG9yX2lkIjoiNzE4ODE2NzcxNzc0ODEzNTYxNiIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 6ff25a64d26027974a1773a39613e1f6acbeab6d077cbb4e5e7fbfed33fbdfef |
| hovercard-subject-tag | issue:551041494 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node/31387/issue_layout |
| twitter:image | https://opengraph.githubassets.com/28ae63b02eae7de605919419a862ce92bd266575d24e6573b4697d69b043f249/nodejs/node/issues/31387 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/28ae63b02eae7de605919419a862ce92bd266575d24e6573b4697d69b043f249/nodejs/node/issues/31387 |
| og:image:alt | Hello all, It would be great if streams internal methods such as _write, _transform would support also a promise based implementation. To clarify what I mean, here's an example. Classic implementat... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | lmammino |
| hostname | github.com |
| expected-hostname | github.com |
| None | 41b6ab3ba6d20a71766ac245b5a4a94c6fc672a9cd4da7d44c1b33ab8bf6a21c |
| turbo-cache-control | no-preview |
| go-import | github.com/nodejs/node git https://github.com/nodejs/node.git |
| octolytics-dimension-user_id | 9950313 |
| octolytics-dimension-user_login | nodejs |
| octolytics-dimension-repository_id | 27193779 |
| octolytics-dimension-repository_nwo | nodejs/node |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 27193779 |
| octolytics-dimension-repository_network_root_nwo | nodejs/node |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | c37fe3e3f5f306900bd5b6bee97463f66c938b2c |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width