加载大量项目时的尾递归

Posted

技术标签:

【中文标题】加载大量项目时的尾递归【英文标题】:Tail recursion when loading lot of items 【发布时间】:2018-03-24 15:02:58 【问题描述】:

我需要从允许我一次仅加载一个文件的 api 加载大量小文件。由于它们非常小,我一次开始几个下载。根据结果​​,我开始下一批加载。

对于每个请求,我使用一个 observable,然后将几个与 combineLatest 结合起来。在combineLatest 之后,我对flatMapconcat 进行了对同一函数的新调用。

作为抽象我这样做 - 伪代码,不编译

func loadRecursively(items) -> Observable<XY> 
    combineLatest(requestObservables)
    .flatMap 
        return loadRecursively(items-loadedItems)
    

这通常非常有效。

问题:这会导致递归尾部不断增长,而编译器优化似乎并未将其切断。因此,当加载数千个文件时,堆栈会增长,最终应用程序将关闭。

如何避免不断增长的尾巴?或者一般来说,我将如何使用 rx 解决这个问题?

【问题讨论】:

嗨,@beseder。我的回答对你有帮助吗?或者你用不同的方式解决你的问题? 【参考方案1】:

RxSwiftconcatMap 运算符(因为人们曾经遇到过same problem),它允许您顺序循环通过您的Observables。

简单示例:

Observable.from([1, 2, 3, 4])
    .concatMap(Observable.just)
    .subscribe(onNext: 
        print($0)
    )
    .disposed(by: bag)

打印:

1
2
3
4

【讨论】:

以上是关于加载大量项目时的尾递归的主要内容,如果未能解决你的问题,请参考以下文章

Oz 中的尾递归优化

一个很Cool的Idear->Python的尾递归优化

XSLT 2.0 中的尾递归函数不起作用

方程 Tn=n∑k=1 =k 的尾递归函数

如何在 Scala 中使用 Stream.cons 编写不泄漏的尾递归函数?

尾递归