Node.js 试图让我自己的RxJs可以被观察到
我正在尝试转换一个现有的API来使用RxJS。。。对node来说是相当新的,对RxJs来说也是非常新的,所以请耐心听我说 我有一个现有的API(getNextMessage),它要么阻塞(异步),要么通过一个节点样式(err,val)回调返回一个新的项或错误,当something变得可用时 所以它看起来像: getNextMessage(nodeStyleCompletionCallback) 您可以将getNextMessage想象为http请求,它将在将来服务器响应时完成,但您确实需要在收到消息后再次调用getNextMessage,以继续从服务器获取新项目 因此,为了使它成为一个可观察的集合,我必须让RxJs继续调用我的getNextMessage函数,直到用户被释放() 基本上,我正在尝试创建自己的RxJs可观察集合 问题是:Node.js 试图让我自己的RxJs可以被观察到,node.js,rxjs,Node.js,Rxjs,我正在尝试转换一个现有的API来使用RxJS。。。对node来说是相当新的,对RxJs来说也是非常新的,所以请耐心听我说 我有一个现有的API(getNextMessage),它要么阻塞(异步),要么通过一个节点样式(err,val)回调返回一个新的项或错误,当something变得可用时 所以它看起来像: getNextMessage(nodeStyleCompletionCallback) 您可以将getNextMessage想象为http请求,它将在将来服务器响应时完成,但您确实需要在收到
var Rx = require('rx');
var port = require('../lib/port');
var async = require('async');
function observableReceive(portName)
{
var observerCallback;
var listenPort = new port(portName);
var disposed = false;
var asyncReceive = function(asyncCallback)
{
listenPort.getNextMessage(
function(error, json)
{
observerCallback(error, json);
if (!disposed)
setImmediate(asyncCallback);
}
);
}
return function(outerCallback)
{
observerCallback = outerCallback;
async.forever(asyncReceive);
}
}
var receive = Rx.Observable.fromNodeCallback(observableReceive('rxtest'));
var source = receive();
var subscription = source.forEach(
function (json)
{
console.log('receive completed: ' + JSON.stringify(json));
},
function (error) {
console.log("receive failed: " + error.toString());
},
function () {
console.log('Completed');
subscription.dispose();
}
);
所以我可能会这么做
var Rx = require('Rx');
// This is just for kicks. You have your own getNextMessage to use. ;)
var getNextMessage = (function(){
var i = 1;
return function (callback) {
setTimeout(function () {
if (i > 10) {
callback("lawdy lawd it's ova' ten, ya'll.");
} else {
callback(undefined, i++);
}
}, 5);
};
}());
// This just makes an observable version of getNextMessage.
var nextMessageAsObservable = Rx.Observable.create(function (o) {
getNextMessage(function (err, val) {
if (err) {
o.onError(err);
} else {
o.onNext(val);
o.onCompleted();
}
});
});
// This repeats the call to getNextMessage as many times (11) as you want.
// "take" will cancel the subscription after receiving 11 items.
nextMessageAsObservable
.repeat()
.take(11)
.subscribe(
function (x) { console.log('next', x); },
function (err) { console.log('error', err); },
function () { console.log('done'); }
);
我意识到这已经有一年多的历史了,但我认为更好的解决方案是使用递归调度:
Rx.Observable.forever = function(next, scheduler) {
scheduler = scheduler || Rx.Scheduler.default,
//Internally wrap the the callback into an observable
next = Rx.Observable.fromNodeCallback(next);
return Rx.Observable.create(function(observer) {
var disposable = new Rx.SingleAssignmentDisposable(),
hasState = false;
disposable.setDisposable(scheduler.scheduleRecursiveWithState(null,
function(state, self) {
hasState && observer.onNext(state);
hasState = false;
next().subscribe(function(x){
hasState = true;
self(x);
}, observer.onError.bind(observer));
}));
return disposable;
});
};
这里的想法是,您可以在前一个项目完成后安排新项目。调用调用传入方法的next()
,当它返回一个值时,安排调用下一项
然后您可以这样使用它:
Rx.Observable.forever(getNextMessage)
.take(11)
.subscribe(function(message) {
console.log(message);
});
查看一个工作示例非常感谢!我自己也算出了其中的一半,并且有点让它工作起来了,尽管我还没有摆脱async。现在我可以建立我自己的第一类观测,这是一个美丽的世界。顺便说一句,这是一个很好的例子——应该放在RxJs文档的某个地方。再次感谢。