填充zip()未定义

时间:2018-01-04 21:15:01

标签: rxjs

以下

Rx.Observable.zip(
     Rx.Observable.of(1,2),
     Rx.Observable.of("a"))
  .subscribe(p => console.log(p))

产生

1,a

这是有道理的,但我希望它产生的是

1,a
2,undefined

我想用未定义的填充较短的observable直到较长的一个完成。有什么建议吗?

3 个答案:

答案 0 :(得分:1)

我意识到添加延迟可以使.of运算符异步并且使用扫描可以用undefine替换相同的值

Rx.Observable.combineLatest(
 Rx.Observable.of(1,2).delay(0),
 Rx.Observable.of("a"))
 .scan((acc,curr)=>{
    acc[1]=acc[1]==curr[1]?undefined:curr[1]
    acc[0]=acc[0]==curr[0]?undefined:curr[0]
return acc
 },[])
 .subscribe(p => console.log(p))

答案 1 :(得分:1)

我认为关键是确保所有源可观察量都相同。

一种解决方案是组成一个可观察的计数器,只要最长的源可观察到。然后它可以连接到较短的源可观察量,如下所示:



const pad = (...sources) => Rx.Observable.create(observer => {

  // Publish the source observables to make them multicast
  // and to allow the subscription order to be managed.

  const publishedSources = sources.map(source => source.publish());

  // Create an observable that emits an incremented index and
  // is as long as the longest source observable.

  const counter = Rx.Observable
    .merge(...publishedSources.map(
      source => source.map((unused, index) => index)
    ))
    .scan((max, index) => Math.max(max, index), 0)
    .distinctUntilChanged()
    .publish();

  // Zip the published sources, contatenating the counter so
  // that they are all the same length. When the counter
  // emissions are concatenated, they are mapped to undefined.

  const subscription = Rx.Observable.zip(...publishedSources.map(
    source => source.concat(counter.mapTo(undefined))
  )).subscribe(observer);

  // Connect the counter and the published sources.

  subscription.add(counter.connect());
  publishedSources.forEach(
    source => subscription.add(source.connect())
  );
  return subscription;
});

pad(
  Rx.Observable.of(1, 2),
  Rx.Observable.of("a")
).subscribe(padded => console.log(padded));

.as-console-wrapper { max-height: 100% !important; top: 0; }

<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

我自己的解决方案如下。这个想法是所有的可观察对象都被转换成无穷无尽的流,从原始值开始,包含在对象中,然后是无数个未定义的。这些无尽的流被连接起来,只要任何值都是原始值,就会得到结果。

@ECHO off
setlocal EnableDelayedExpansion
set "VAR=da da da YES123123"
echo %VAR% > testing.txt

FOR /F %%a in ('findstr "YES" .\testing.txt') do (
                                                 set BLAH=%%a
                                                 set "BLAH2=%BLAH: =%"
                                                 set "FINAL=%BLAH2:~15%"
                                                 echo %FINAL%
                                                 )

endlocal
const unending = (obs) => 
  obs.map(value => ({value}))
     .concat(Rx.Observable
               .interval(0)
               .mapTo(undefined));

const zipPad = (...obss) => 
  Rx.Observable.zip(...obss.map(unending))
    .takeWhile(p => p.find(v => v))
    .map(p => p.map(v => v && v.value));

zipPad(Rx.Observable.of(1,2,3),
       Rx.Observable.of("a"),
       Rx.Observable.of("x", "y"))
.subscribe(p => console.log(p));

欢迎任何人改进这个答案并在此发布他们的变体。