我正在尝试根据下游条件过滤掉更多上游项目。 mapProcess本质上启动一个Process(脚本或exe)。该过程可能需要一些时间才能完成,我想在完成之前忽略任何进一步的上游项目。 createProcess还返回一个Obdable of StdOut。我们切换到createProcess创建的IObservable并将arg映射到StdOut。
实施例
let mapProcess obs =
obs
|> Observable.map (fun arg -> createProcess arg)
|> Observable.switch
我做了什么:这有效,但对这里的可变性并不完全满意。
let mapProcess obs =
let mutable processNotRunning = true
obs
|> Observable.filter (fun _ -> processNotRunning)
|> Observable.map (fun arg -> processNotRunning <- false
createProcess arg)
|> Observable.switch
|> Observable.iter (fun _ -> processNotRunning <- true)
|> Observable.finallyDo (fun _ -> processNotRunning <- true)
我认为我可能需要的是某种“switchIfSeen”Observable函数,只有在当前订阅的observable已生成项目或已完成时才会切换。我可能只是通过组合一些现有的RX功能而错过了一种更简单的方法吗?
答案 0 :(得分:2)
[...]仅在当前订阅的observable产生了一个时才切换 项目或已完成
忽略值的一种方法是将热观察值转换为冷可观察量 - 因此无论谁在聆听,它都可以推出项目。然后,你只在需要的时候听。
var map = argn.Select(CreateProcess).Publish().RefCount();
map.SelectMany(o => o) //flatmap
.Take(1)
.Repeat()
.Subscribe(d => Console.WriteLine($"Did task which took {d * 100}msecs" ));
测试:
(CreateProcess
只是一个定时器,它会产生x100毫秒的固定延迟。)
private static void Main(string[] args)
{
var argn = Observable.Interval(TimeSpan.FromMilliseconds(100)).Publish().RefCount();
argn.Subscribe(Console.WriteLine);
var map = argn.Select(CreateProcess).Publish().RefCount();
map.SelectMany(o => o)
.Take(1)
.Repeat()
.Subscribe(d => Console.WriteLine($"Did task which took {d * 100}msecs" ));
Console.ReadKey();
}
static IObservable<long> CreateProcess(long i) => Observable.Timer(TimeSpan.FromMilliseconds(i * 100)).Select(_ => i);
输出:
0
Did task which took 0msecs
1
2
Did task which took 100msecs
3
4
5
Did task which took 300msecs
6
7
8
9
10
11
Did task which took 600msecs