我有2个可观察值。第一个发出numbers
,第二个发出strings
。
这两个Observables在某些触发器发出时开始发出。触发是主题,两个可观察对象中的每个都有其自己的触发。
我想在两个Observable之间开始race
,以便其触发发出第一个获胜的Observable并开始发出,而另一个触发则随后触发也被忽略。
这是代码
const observableOfNumber = interval(100).pipe(take(10));
const observableOfNumberFunction = () => observableOfNumber;
const observableOfString = interval(100).pipe(map(number => String.fromCharCode(65 + number)), take(10));
const observableOfStringFunction = () => observableOfString;
const startEmittingNumbers = new Subject<any>()
const emittingNumbers = startEmittingNumbers
.pipe(
map(() => observableOfNumberFunction),
);
const startEmittingChars = new Subject<any>()
const emittingChars = startEmittingChars
.pipe(
map(() => observableOfStringFunction),
);
race(emittingNumbers, emittingChars)
.pipe(
mergeMap(handler => handler())
)
.subscribe(console.log);
此代码使Typescript出现以下错误
尽管如此,该代码在本质上似乎运行良好。
如果我只是将observableOfStringFunction
的返回类型声明为Observable<any>
,即
const observableOfStringFunction = (): Observable<any> => observableOfString;
Typescript不再抱怨,一切正常。
类似地,如果我不是使用race
而是使用merge
,即使从类型检查的角度来看,merge
和race
应该使用Typescript也不会抱怨表现相同。
有人能指出我这种不同行为的原因吗?
答案 0 :(得分:2)
之所以会发生这种情况,是因为race
返回的 type 与 type 相同,后者首先从其参数发出(例如,比赛获胜者)-{ {1}}。
在您的示例中,竞赛获胜者的类型为Observable<T>
,因为类型检查器可能(也可能)将第一个参数的类型也作为返回类型进行评估,然后期望随后的每个发射都相同类型(不是)。如果要改变参数,您会注意到IntelliSense将为您的number
参数带来相同的错误。这就是为什么IDE抱怨但代码仍然可以运行的原因。
这是一个更明确的示例:
emittingNumbers
const obs1 = interval(1000).pipe(mapTo('fast one')); // Emits first, type string
const obs2 = interval(3000).pipe(mapTo(1)); // Type number, TypeScript will complain
const obs3 = interval(5000).pipe(mapTo('slow one'));
race(obs3, obs1, obs2)
.subscribe(
winner => console.log(winner)
);
const {
Observable,
interval,
Subject,
race
} = rxjs;
const {
map,
take,
mergeMap,
mapTo
} = rxjs.operators;
const obs1 = interval(1000).pipe(mapTo('fast one'));
const obs2 = interval(3000).pipe(mapTo(1)); // TypeScript will complain about this
const obs3 = interval(5000).pipe(mapTo('slow one'));
race(obs3, obs1, obs2)
.subscribe(
winner => console.log(winner)
);