使用Bluebird.js和Twitterstream承诺和stream

我对Promise和Node是一个新超级新手,对于使用承诺和stream感到好奇。 我可以promisifystream? 使用Bluebirdjs和Twit模块我有以下几点:

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) }) }); 

运行此代码不会logging推文,也不会引发错误。 没有任何事情发生,似乎有什么联系,但没有任何的承诺工作。

原始片段,在尝试实施在twit文件中发现的承诺之前

 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) }) 

我很遗憾地说,这是行不通的,因为承诺和stream之间有根本的区别。 你说你们都是新手,所以让我简单介绍一下。

承诺可以被看作是可能还没有到达的单一价值的占位符。 例如,一些假设的函数getTweet()可以像这样工作:

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

但这会让你只有一个鸣叫! 为了得到另一个,你必须再次调用getTweet() ,并在后面添加一个新的getTweet() 。 事实上,当使用promise时,你可以保证.then()只能一次调用它的包含函数!

数据stream是连续的数据stream。 您不必手动要求推特,然后再推出另一个,然后再推。 你打开水龙头,然后它会一直到来,直到它完成,或者你告诉它停止。

所以,总之,你不能promisify一个stream,因为承诺是单个值和stream连续的数据stream。

我假设你问这个问题,因为你喜欢承诺接口,并希望使用类似的东西stream? 根据你想要达到的目标,有不同的库可以使stream处理更好。 EventStream就是一个例子。 让我知道你的计划,我可能会给你一个例子。

我结束了使用RxJS与stream实施observables。

 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); 

我最终不得不使用RX.Observable.fromEvent而不是Rx.Node.fromStream,因为Twit模块必须在幕后处理实际的stream,但通过EventEmitter暴露出来,他们可能不应该把它命名为T.stream。

我可以promisifystream?

没有。当一个stream不断地发生事件,一个承诺只解决一次。 他们有完全不同的语义(即使都使用asynchronouscallback)。

可以对stream结束做出承诺,请参阅BlueBirds文档中的EventEmitterPromisifier示例 – 但这不是您的Twitterstream示例所做的。

运行此代码不会logging推文,也不会引发错误。

因为T.stream()是一个返回stream对象的同步工厂函数。 你不需要 – 你不能 – 使用streamAsync ,因为它永远不会调用隐式传递的callback。