Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promises and streams using Bluebird.js and Twitter stream

I am new super new to Promises and Node and am curious about using promises with streams. Can I promisify a stream? Using Bluebirdjs and the Twit module I have the following:

var Twit = require('twit')
var Promise = require("bluebird");

var T = new Twit({
 consumer_key:         process.env.CONSUMER_KEY,
 consumer_secret:      process.env.CONSUMER_SECRET,
 access_token:         process.env.ACCESS_TOKEN,
 access_token_secret:  process.env.ACCESS_TOKEN_SECRET
})

Promise.promisifyAll(Twit);
Promise.promisifyAll(T);

var sanFrancisco = [ '-122.75', '36.8', '-121.75', '37.8' ]

T.streamAsync('statuses/filter', { locations: sanFrancisco })
.then(function(connection){
 connection.onAsync('tweet')
  .then(function (tweet) {
   console.log(tweet)
  })
});

Running this code does not log a tweet and no error is thrown. Nothing happens the connection seems to be made but none of the .then promises work.

The original snippet, before trying to implement promises found in the twit docs

var sanFrancisco = [ '-122.75', '36.8', '-121.75', '37.8' ]

var stream = T.stream('statuses/filter', { locations: sanFrancisco })

stream.on('tweet', function (tweet) {
 console.log(tweet)
})
like image 454
srm Avatar asked Mar 12 '15 15:03

srm


1 Answers

I'm sorry to say that won't work, because of a fundamental difference between a promise and a stream. You say you're new to both, so let me give you a short introduction to both.

Promises can be seen as placeholders for some single value that might not have arrived yet. For instance, some hypothetical function getTweet() could work like this:

getTweet()
    .then(function (tweet) {
        //Do something with your tweet!
        console.log(tweet);
    });

But this would get you just a single tweet! To get another one, you'd have to call getTweet() again, with a new .then() behind that. In fact, when working with promises you have the guarantee that a .then() calls its containing function only a single time!

Streams are continuous flows of data. You don't have to manually ask for a tweet, and then another one, and then another one. You open the tap, and then it just keeps coming until either it's finished or you tell it to stop.

So, in summary, you can't promisify a stream, because promises are for single values and streams for continuous flows of data.

I assume you asked the question because you like the promise interface and would like to use something similar for streams? Depending on what you're trying to achieve, there are different libraries that can make working with streams nicer. EventStream is one example. Let me know what you plan and I might be able to give you an example.

like image 73
Jasper Woudenberg Avatar answered Sep 24 '22 03:09

Jasper Woudenberg