使用Bluebird.js和Twitter流的Promise和流

时间:2015-03-12 15:30:23

标签: javascript node.js promise bluebird

我是Promises和Node的新手,并且对使用流的Promises感到好奇。我可以宣传一个流吗? 使用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)
  })
});

运行此代码不会记录推文,也不会引发任何错误。似乎没有任何事情发生连接,但没有任何.then承诺有效。

原始代码段,然后尝试实施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)
})

3 个答案:

答案 0 :(得分:12)

我很遗憾地说,由于承诺和流之间存在根本区别,因此无效。你说你对两者都不熟悉,所以让我简单介绍一下。

承诺可以被视为可能尚未到达的某些单一价值的占位符。例如,一些假设函数getTweet()可以这样工作:

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

但这只会让你发一条推文!要获得另一个,您必须再次致电getTweet(),后面会有一个新的.then()。事实上,在使用promises时,您可以保证.then()只调用其包含的函数一次!

Streams是连续的数据流。您不必手动询问推文,然后是另一个推文,然后是另一个推文。你打开水龙头,它就会一直持续到它完成或你告诉它停止。

因此,总而言之,您无法宣传流,因为承诺是针对连续数据流的单个值和流。

我假设您问了这个问题,因为您喜欢promise接口,并希望对流使用类似的东西?根据您要实现的目标,有不同的库可以更好地处理流。 EventStream就是一个例子。让我知道你的计划,我可以给你一个例子。

答案 1 :(得分:4)

我最终使用RxJS使用streams实现了observable。

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模块必须处理幕后的实际流但是通过它和EventEmitter公开它们,它们可能不应该命名为T .stream。

答案 2 :(得分:1)

  

我可以宣传一个流吗?

没有。当流不断发出事件时,承诺只会解析一次。它们具有完全不同的语义(即使两者都使用异步回调)。

可以对结束的流做出承诺,请参阅EventEmitterPromisifier example in BlueBirds documentation - 但这不是您的Twitter流示例所做的。

  

运行此代码不会记录推文,也不会引发任何错误。

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