[ANN] promise-stream: Turn a stream into a commonJS promise

301 views
Skip to first unread message

Raynos

unread,
Oct 3, 2012, 12:40:02 AM10/3/12
to nod...@googlegroups.com
https://github.com/Raynos/promise-stream

If you want to turn a stream into a promise you can.

This mainly illustrates how streams and promises are similar for those that like promises.

It also shows a comparison between how you flow async code through promises and streams

Mariusz Nowak

unread,
Oct 3, 2012, 4:11:56 AM10/3/12
to nod...@googlegroups.com
Raynos, I have a feeling that you are comparing apples and oranges. Streams are awesome, Promises are awesome but it's not the same, and not every use case can be addressed on equal level by both of them.

From my experience there can be promises that are also a streams, but among them are also promises that fulfill before stream ends. There can also be promises that are not streams, of course you may represent them as stream but if they bring no value and just emit 'end', it doesn't fit well stream concept, does it?

Same way you can just use callbacks instead of promises, but the point is that promises gives you better abstraction, so it's easier to construct complicated flow with it and maintain it. See this: https://github.com/medikoo/deferred#promises-approach How would you write it with streams instead? Would it be more friendly than callbacks version: https://github.com/medikoo/deferred#plain-nodejs ?

Jake Verbaten

unread,
Oct 3, 2012, 12:39:52 PM10/3/12
to nod...@googlegroups.com
Streams are the better abstraction for that.

Notice that with the streams version you can actually start writing to the disk once you've successfully loaded a single file.

```
var chain = require("chain-stream")
    , fs = require("fs")
    , DirStream = require("dir-stream") // to be written
    , d = require("domain").create()

d.run(function () {
    chain(DirStream(__dirname))
        .filter(function (fileName) {
            return (file.slice(-3) === ".js" && (file !== "lib.js"))
        })
        .map(readFile)
        .pipe(fs.createWriteStream(__dirname + "/lib.js"))
})

d.on("error", function ignoreIt() {})
```

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Jake Verbaten

unread,
Oct 3, 2012, 1:11:04 PM10/3/12
to nod...@googlegroups.com
The other feature is that this is all in node core. Isaacs 0.9 streams will have the notion of a transform stream.

We can also petition node core to make fs.createReadStream(dirname) work because a directory is just a fd with a list of files so it should work.

Then the program becomes

```
var fs = require("fs")
    , d = require("domain").create()
    , Transform = require("stream").Transform

d.run(function () {
    var onlyJsFiles = new Transform()
        , mapToFiles = new Transform()
        , addNewLine = new Transform()

    onlyJsFiles._transform = function(fileName, output, end) {
        if (fileName.slice(-3) === ".js" && (fileName !== "lib.js")) {
            output(fileName)
        }
        end()
    }

    mapToFiles._transform = function(fileName, output, end) {
        fs.readFile(fileName, end)
    }

    addNewLine._transform = function (file, output, end) {
        end(null, file + "\n")
    }

    fs.createReadStream(__dirname)
        .pipe(onlyJsFiles)
        .pipe(mapToFiles)
        .pipe(addNewLine)
        .pipe(fs.createWriteStream(__dirname + "/lib.js"))
})

d.on("error", function ignoreIt() {})
```

Mariusz Nowak

unread,
Oct 3, 2012, 1:38:38 PM10/3/12
to nod...@googlegroups.com
Raynos, Streams are very powerful and I agree with that, but as your examples shown you just cannot take asynchronous functions and configure them with streams directly, so they're not that helpful when dealing with asynchronicity that's not stream based.

You're point is not against promises but rather against typical asynchronous CPS. Question is whether you can (or whether it makes sense) to address all asynchronicity use cases with Streams, I doubt whether it make sense.

You made a one good point about writing to file while, having already some files ready, this is where indeed streams win, I was thinking about it recently. Currently in deferred implementation promise is an event-emitter, with 0.7 I want to push it forward so it can also be stream (both readable and writable). I've got use cases where it's beneficial to have promises that are also streams.

Anyway I find a lot of great stuff in your examples. Thanks for sharing that!

Jake Verbaten

unread,
Oct 3, 2012, 2:59:09 PM10/3/12
to nod...@googlegroups.com
promises only work if everything is a promise. Streams only work if everything is a stream.

Making everything a stream is cool because streams represent the endless flow of data through your entire program. It's basically doing reactive programming.

Making everything a stream instead of a promise has the advantage of most things in node core are already streams. Domains work cleanly with streams, etc.

Oh and streams are composable! You write a stream I can use it with any of my streams. You write a promise, I have to use promises everywhere or ignore all your work.
Reply all
Reply to author
Forward
0 new messages