将每个源值投影到同一个Observable,该Observable在输出Observable中使用switchMap多次展平。输入一个Observable并输出一个函数Operator。实际上是一个函数,每次在源Observable上发出一个值时都会返回一个新的Observable。此函数从给定的innerObservable发出项目,并且仅从最近投影的内部Observable获取值。看一个例子:import{EMPTY,range}from'rxjs';import{first,take,tap}from'rxjs/operators';从'rxjs'导入{fromEvent,interval};从'rxjs/operators''导入{switchMapTo};constclicks=fromEvent(document,'click');常量测试=事件=>控制台。日志('杰瑞:',事件);常量结果=点击。pipe(tap(test),switchMapTo(interval(1000)));result.subscribe(x=>console.log(x));输出:每次点击后,click$抛出的PointerEvent被switchMapTo返回的FunctionOperator丢弃。最后,在用户订阅时的result函数中,打印的值是switchMapTo输入的interval(1000)Observable发出的值,而不是clicks$抛出的PointerEvent。让我们看另一个在网页上显示倒计时数字的例子。import'./style.css';import{interval,fromEvent}from'rxjs';import{switchMapTo,scan,startWith,takeWhile,finalize}from'rxjs/operators';constCOUNTDOWN_TIME=10;//引用constcountdownElem=document.getElementById('countdown');//流constclick$=fromEvent(document,'click');constcountdown$=interval(2000).pipe(scan((acc,_)=>--acc,COUNTDOWN_TIME),startWith(COUNTDOWN_TIME));click$.pipe(switchMapTo(countdown$),takeWhile(val=>val>=-10),finalize(()=>(countdownElem.innerHTML="We'redonehere!"))).subscribe((val:any)=>(countdownElem.innerHTML=val));初始整数为10,每2秒减1,到-10时停止。思路:触发计数器开始递减的操作是点击屏幕,所以需要用fromEvent构造Observable:click$每两秒执行一次操作,所以需要用interval构造第二个Observable。一旦计数器启动,每两秒Seconds需要递减一次,因此您需要使用switchMapTo将click$映射到intervalObservable。传值后与click$无关。因为是自减操作,暗示这是一个有状态的场景,所以使用扫描算子来维护内部状态。更多Jerry原创文章在这里:《王子熙》:
