【问题标题】:Angular 2 RxJS Does the Zip Operator have a limit on arguments?Angular 2 RxJS Zip 运算符对参数有限制吗?
【发布时间】:2020-02-01 00:36:30
【问题描述】:

我现在对导致此错误的原因感到困惑。我正在尝试压缩 7 个 Observables 的结果,例如:

var zipped$ = Observable.zip(
    Observable.of({prop1:1}),
    Observable.of({prop2:2}),
    Observable.of({prop3:3}),
    Observable.of({prop4:4}),
    Observable.of({prop5:5}),
    Observable.of({prop6:6}),
    Observable.of({prop7:7})
);

然后将它们与 mergeAll() 和 reduce() 合并,如:

var reduced$ = zipped$.mergeAll().reduce((acc,val) => Object.assign({},acc,val));
reduced$.subscribe(final => console.log(final));

但我收到此错误:“类型 '{}' 上不存在属性 'reduce'”

为了增加混乱:

如果我使用 6 个值,它可以正常工作。

如果 observables 都返回原语,它工作正常。

如果我将此函数添加为 zip 中的最后一个参数:

function(...args: any[]) {
    // I have no ieda why I need this hack, but the zip fails without it.
    return args;
}

它工作正常。

这是 RxJS 中的错误吗?我是否遗漏了有关 zip 实施的一些信息?这是角度编译器的东西吗?没有多少搜索文档显示 zip 的参数数量有限制。任何见解都值得赞赏。

谢谢

编辑:对于任何其他发现此内容的人。

最好的解决方法是将 observables 粘贴在一个数组中并将其作为单个参数提供,例如:

var zipped$ = Observable.zip(...[
    Observable.of({prop1:1}),
    Observable.of({prop2:2}),
    Observable.of({prop3:3}),
    Observable.of({prop4:4}),
    Observable.of({prop5:5}),
    Observable.of({prop6:6}),
    Observable.of({prop7:7})]);

这也很好用。编辑:数组提要停止工作,现在需要使用扩展运算符和数组。

【问题讨论】:

  • 它与 TypeScript 相关。请注意,显式类型的重载仅上升到 T6: github.com/ReactiveX/rxjs/blob/master/src/operator/zip.ts 之后,它会将签名与变量参数匹配。具体怎么回事,我不知道。我以后可能会看看。
  • 这至少澄清了正在发生的事情。我觉得这至少应该在文档中。感谢您的洞察力,非常感谢。如果您回答,我会将其标记为已回答。
  • 当我确切地知道发生了什么时,我会发布一个答案。指定项目函数时没问题的事实表明可能缺少重载签名。
  • 听起来不错,很想看看你发现了什么。我也将其发布到 GitHub。那里有人回应了,事实证明,如果您只是将一组可观察对象作为单个参数提供给 zip,而不是将每个对象作为单独的参数传递,那么它也可以工作。

标签: javascript angular rxjs


【解决方案1】:

自 2017 年以来发生了很多变化,如今的 rxjs 文档非常好,几乎涵盖了人们可能想要的所有内容。

现在让我们深入探讨这个问题。

首先,旧的 zip 运算符(可在此处找到:old zip)现在已弃用,取而代之的是新的 zip(可在此处找到:zip

主要区别在于旧的操作符是一个可链接的操作符,它的使用方式是这样的(后来它变成了管道):

of(1).pipe( zip(of(2)),map(([a,b]) => ({a,b}))).subscribe(x => console.log(x) // {a:1, b:2})

虽然新的操作符是一个创建操作符,并且使用方式如下:

zip(of(1),of(2)).pipe(delay(1000),map(([a,b]) => ({a,b}))).subscribe(x => console.log(x) // {a:1, b:2})

关于这个问题,你可以在 zip 操作符中传递的 observables 的数量没有限制,例如下面的 sn-p 将起作用

let arr = (new Array(100)).fill(false).map((x,i)=> of({[`key${i}`]:i}))
zip(...arr).pipe(
  mergeAll(),
  reduce((acc,val) => Object.assign({},acc,val)),
)

但是,如果您使用 typescript 并传递超过 6 个不同类型的 observable,您将丢失类型和自动补全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多