Promises and streams using streams Bluebird.js and Twitter

I am new super new for Promises and Node, and I am curious to use Promises with streams. Can I roll over the flow? 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 record tweets and does not produce an error. Nothing happens, the connection seems to be in progress, but not one of them. Then Promises does not work.

Original snippet before trying to implement Promises found in 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) }) 
+6
source share
3 answers

I'm sorry to say that this will not work because of the fundamental difference between the promise and the flow. You say that you are new to both, so let me give you a brief introduction to both.

Promises can be thought of as placeholders for some single value that may not have arrived yet. For example, some hypothetical getTweet() functions may work as follows:

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

But it will bring you just one tweet! To get another one, you have to call getTweet() again, with the new .then() . In fact, when working with promises, you have a guarantee that .then() calls its containing function only once!

Streams are continuous streams of data. You do not need to manually request tweets, and then another, and then another. You open the tap, and then it just continues until it finishes, or you stop it.

So, in general, you cannot promise a stream, because promises are for single values ​​and streams for continuous data streams.

I assume you asked a question because you like the promise interface and want to use something similar for streams? Depending on what you are trying to achieve, there are different libraries that can improve work with streams. EventStream is one example. Let me know what you are planning, and I could give you an example.

+11
source

I ended up using the RxJS implementation of observables with streams .

 var sanFrancisco = [ '-122.75', '36.8', '-121.75', '37.8' ] var stream = T.stream('statuses/filter', { locations: sanFrancisco }); var source = Rx.Node.fromEvent(stream, 'tweet'); var observer = Rx.Observer.create( function (tweet) { // THIS IS WHERE EACH TWEET SHOULD COME FROM THE STREAM console.log(tweet); }, function (err) { console.log('Error getting tweets: ' + err); }, function () { console.log('Completed'); } ); source.subscribe(observer); 

I had to use RX.Observable.fromEvent instead of Rx.Node.fromStream, because the Twit module should process the actual stream backstage, but exposing it to EventEmitter, they probably shouldn't have called it T.stream.

+4
source

Can I roll over the flow?

No. Although a stream continuously emits events, a promise is only allowed once. They have completely different semantics (even if both use asynchronous callbacks).

You can make a promise for a stream that ends, see the EventEmitterPromisifier example in the BlueBirds documentation - but this is not what your Twitter stream example is.

Running this code does not record tweets and does not produce an error.

Because T.stream() is a synchronous factory function that returns a stream object. You do not need - you cannot - use streamAsync , as it will never call an implicitly passed callback.

+1
source

Source: https://habr.com/ru/post/983707/


All Articles