RxJS zip() 运算符未按预期工作。它总是在不触发任何值的情况下完成
RxJS zip() operator doesn't work as expected. It always completes without triggering any value
场景:当有一个包含很多元素的可观察对象时,例如 450+,我想将这些元素以 100 个元素为一组添加到不同的可观察对象中。
您可以在这里找到一个工作示例:https://stackblitz.com/edit/rxjs-au9pt7?file=index.ts that @martin provided me as part of the answer to this question:
stackblitz 非常有效,但我正在努力在 Angular 中实现它。可观察对象(zip 运算符的结果)在没有触发任何单个值的情况下完成,但正如您在工作示例中看到的那样,它工作得非常好。我一定是遗漏了什么,但我不确定到底是什么。
component.ts
import { Component, AfterViewInit } from '@angular/core';
import { zip, Observable, fromEvent, range } from 'rxjs';
import { map, bufferCount, startWith, scan } from 'rxjs/operators';
import { MultiSelectService, ProductCategory } from './multiselect.service';
@Component({
selector: 'multiselect',
templateUrl: './multiselect.component.html',
styleUrls: ['./multiselect.component.scss']
})
export class MultiselectComponent implements AfterViewInit {
SLICE_SIZE = 100;
categories$: Observable<Array<ProductCategory>>;
constructor(private data: MultiSelectService) {
this.categories$ = data.categories$;
}
ngAfterViewInit() {
const loadMore$ = fromEvent(document.getElementsByTagName('button')[0], 'click');
const data$ = range(450);
zip(
data$.pipe(bufferCount(this.SLICE_SIZE)),
loadMore$.pipe(startWith(0)),
).pipe(
map(results => results[0]),
scan((acc, chunk) => [...acc, ...chunk], []),
).subscribe({
next: v => console.log(v),
complete: () => console.log('complete'),
});
}
}
template.html
<button>load more</button>
在此先致谢,非常感谢任何帮助。
我认为你误解了 zip,zip 会交错两个 observables 的结果。
const { from, zip } = rxjs;
const nums$ = from([1, 2, 3, 4]);
const strings$ = from(['a', 'b', 'c', 'd']);
zip(nums$, strings$).subscribe(([num, str]) => { console.log(`${num} - ${str}`); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>
由于某些奇怪的原因,RxJS 版本 6.3.3 导致了这个问题。升级到 RxJS 6.4.0 解决了这个问题。
场景:当有一个包含很多元素的可观察对象时,例如 450+,我想将这些元素以 100 个元素为一组添加到不同的可观察对象中。
您可以在这里找到一个工作示例:https://stackblitz.com/edit/rxjs-au9pt7?file=index.ts that @martin provided me as part of the answer to this question:
stackblitz 非常有效,但我正在努力在 Angular 中实现它。可观察对象(zip 运算符的结果)在没有触发任何单个值的情况下完成,但正如您在工作示例中看到的那样,它工作得非常好。我一定是遗漏了什么,但我不确定到底是什么。
component.ts
import { Component, AfterViewInit } from '@angular/core';
import { zip, Observable, fromEvent, range } from 'rxjs';
import { map, bufferCount, startWith, scan } from 'rxjs/operators';
import { MultiSelectService, ProductCategory } from './multiselect.service';
@Component({
selector: 'multiselect',
templateUrl: './multiselect.component.html',
styleUrls: ['./multiselect.component.scss']
})
export class MultiselectComponent implements AfterViewInit {
SLICE_SIZE = 100;
categories$: Observable<Array<ProductCategory>>;
constructor(private data: MultiSelectService) {
this.categories$ = data.categories$;
}
ngAfterViewInit() {
const loadMore$ = fromEvent(document.getElementsByTagName('button')[0], 'click');
const data$ = range(450);
zip(
data$.pipe(bufferCount(this.SLICE_SIZE)),
loadMore$.pipe(startWith(0)),
).pipe(
map(results => results[0]),
scan((acc, chunk) => [...acc, ...chunk], []),
).subscribe({
next: v => console.log(v),
complete: () => console.log('complete'),
});
}
}
template.html
<button>load more</button>
在此先致谢,非常感谢任何帮助。
我认为你误解了 zip,zip 会交错两个 observables 的结果。
const { from, zip } = rxjs;
const nums$ = from([1, 2, 3, 4]);
const strings$ = from(['a', 'b', 'c', 'd']);
zip(nums$, strings$).subscribe(([num, str]) => { console.log(`${num} - ${str}`); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>
由于某些奇怪的原因,RxJS 版本 6.3.3 导致了这个问题。升级到 RxJS 6.4.0 解决了这个问题。