【发布时间】:2017-02-15 05:06:21
【问题描述】:
我正在尝试创建一个 observable,它从多个异步操作(来自 Jenkins 服务器的 http 请求)中生成值,一旦所有操作完成,它将让订阅者知道。我觉得我一定是误解了什么,因为这没有达到我的预期。
'use strict';
let Rx = require('rx');
let _ = require('lodash');
let values = [
{'id': 1, 'status': true},
{'id': 2, 'status': true},
{'id': 3, 'status': true}
];
function valuesObservable() {
return Rx.Observable.create(function(observer) {
_.map(values, function(value) {
var millisecondsToWait = 1000;
setTimeout(function() { // just using setTimeout here to construct the example
console.log("Sending value: ", value);
observer.onNext(value)
}, millisecondsToWait);
});
console.log("valuesObservable Sending onCompleted");
observer.onCompleted()
});
}
let observer = Rx.Observer.create((data) => {
console.log("Received Data: ", data);
// do something with the info
}, (error) => {
console.log("Error: ", error);
}, () => {
console.log("DONE!");
// do something else once done
});
valuesObservable().subscribe(observer);
运行这个,我得到输出:
valuesObservable Sending onCompleted
DONE!
Sending value: { id: 1, status: true }
Sending value: { id: 2, status: true }
Sending value: { id: 3, status: true }
虽然我希望看到的更像是:
Sending value: { id: 1, status: true }
Received Data: { id: 1, status: true }
Sending value: { id: 2, status: true }
Received Data: { id: 2, status: true }
Sending value: { id: 3, status: true }
Received Data: { id: 3, status: true }
valuesObservable Sending onCompleted
DONE!
我实际上并不关心列表中项目的顺序,我只想让观察者接收它们。
我相信发生的事情是 Javascript 异步触发超时功能,并立即进入observer.onCompleted() 行。一旦订阅观察者接收到 onCompleted 事件(这是正确的词吗?),它决定它已经完成并自行处理。然后,当异步操作完成并且 observable 触发 onNext 时,观察者将不再存在以对其执行任何操作。
如果我在这点上是对的,我仍然不知道如何让它以我想要的方式运行。我是否在没有意识到的情况下偶然发现了反模式?有没有更好的方法来处理整个事情?
编辑:
自从我使用 setTimeout 构建示例后,我意识到我可以通过给 observable 一个超时时间来使用它来部分解决我的问题。
function valuesObservable() {
return Rx.Observable.create(function(observer) {
let observableTimeout = 10000;
setTimeout(function() {
console.log("valuesObservable Sending onCompleted");
observer.onCompleted();
}, observableTimeout);
_.map(values, function(value) {
let millisecondsToWait = 1000;
setTimeout(function() {
console.log("Sending value: ", value);
observer.onNext(value)
}, millisecondsToWait);
});
});
}
这会按照我想要的顺序(数据,然后完成)从可观察对象中获取所有信息,但是根据超时的选择,我可能会错过一些数据,或者必须等待很长时间才能完成事件.这只是我必须忍受的异步编程的固有问题吗?
【问题讨论】:
-
setTimeout 是异步的,为什么您希望您的订阅在完成之前等待它?
-
@Baumi 我想我解释说我不希望它等待,但我问这个问题是为了获得一些会导致它等待的构造的帮助。这还不清楚吗?您能否建议我如何改写这句话以更好地理解自己?
-
对不起,伙计,我的错误 - 不知怎的,我直到最后才读到这篇文章......
-
朋友别担心。
标签: javascript asynchronous rxjs observable