我想使RxJS可观察,这将同时产生异步请求和超时。
-> promise -> filter -> promise and timeout -> complete
在具有async / await代码的同步版本中,代码如下所示:
(async () => {
const gameInfo = await function1(); // return undefined or {start, id}
if (!gameInfo) {
return;
}
const gameStart = gameInfo.start;
setTimeout(() => {
function3(gameInfo._id).then(res => {
console.log('Done');
});
}, getDelayTime(gameStart));
await function2();
// Completed
})();
const getDelayTime = (time) => {
const now = new Date();
const parsedTime = new Date(time);
console.log('In delay', parsedTime.getTime() - now.getTime());
return parsedTime.getTime() - now.getTime();
};
所以目标是从function1()
异步接收一些数据,然后对它的第一部分进行一些操作,同时启动计时器,在时间结束时进行第二次操作,无论是{{1}结束与否。
所以,在RxJS中我带来了类似的东西:
function3()
但是,我的目标没有按预期工作。
如果我将代码更改为以下内容:
Rx.Observable
.fromPromise(function1())
.filter(data => data)
.concatMap(data => {
Rx.Observable.fromPromise(function2());
Rx.operators.delay(data => Rx.operators.timeout(getDelayTime(data.start)));
})
.subscribe(
data => {
console.log('Data', data);
function3(data._id)
}
err => console.error('Err', err.message),
() => console.log('Completed'),
);
它不起作用。
所以,我的问题是,如何在RxJS中创建并发计时器和异步http请求?
答案 0 :(得分:1)
延迟通话的一种方法是执行timer
后跟*map
(flatMap,switchMap,...)运算符。它将等待持续时间,然后订阅您放在*map
中的任何内容。
您可以使用combineLatest
,withLatestFrom
和类似订阅多个可观察对象。但通常人们想对结果做些什么。
如果您不关心结果,您可以随时使用tap
运算符来触发副作用。或者您可以在订阅中的onNext
回调中执行此操作。
我认为这可以做你想要的,但说实话,这是一个奇怪的用法。如果你可以分享更多关于你想要实现的目标,我们可能会提供更好的建议。
function test(id, timeout) {
console.log('called', id);
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('resolved', id);
resolve();
}, timeout);
});
}
Rx.Observable.fromPromise(test(1, 1000))
.flatMap(() => Rx.Observable.combineLatest(
Rx.Observable.fromPromise(test(2, 3000)),
Rx.Observable.timer(1234).flatMap(() =>
Rx.Observable.fromPromise(test(3, 100)))
))
.subscribe(() => { console.log('onNext'); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.9/Rx.min.js"></script>