Angular 8.未知数量的HTTP.在数组中获取要调用的请求,必须是顺序的,使用什么



我使用了zip,但是事实证明,zip可以平行工作,至少我是如何使用它的,我需要呼叫才能连续。有STH吗?在rjxs aleady?

否则,我将构建一个递归功能,该功能将调用从数组转移,然后返回与confaTmap一起返回并返回相同功能的呼叫。

但是,如果已经有一些RJXS操作员,我当然更喜欢。

这是我的代码

    private mapChildrenOfNode(sourceNode: TreeNode, trx: number) {
        const nodeId = sourceNode.id;
        const urlChildren = config.apiUrl + `/get_children/trx=${trx}&id=${nodeId}`;
        if (sourceNode.children == null || 0 === sourceNode.children.length) {
            return of(sourceNode);
        }
        return this.http.get<TreeNode[]>(urlChildren).pipe(
            map(
                children => {
                    sourceNode.childrenNested = children ? children : [];
                }
            ),
            map(
                () => sourceNode
            ),
            concatMap(
                node => {
                    return zip(...sourceNode.childrenNested.map(
                        childNode => {
                            return this.parseNodeAnswerRecursively(childNode, trx);
                        }
                    )).pipe(
                        map(children => sourceNode.childrenNested = children),
                        map(() => sourceNode),
                    );
                }
            )
        );
    }

更新1

我现在也看到了zip首先要发射所有前飞行前,并且完成后,它将用于数据征用...无法使用。我正在寻找STH。这就像Zip还采用了一系列可观察到的(在我的情况下,http.get&lt;>(url(.pipe((呼叫(,但一个一个呼叫它们。

更新2

我找到了一个解决方案并写了一个答案...

https://stackoverflow.com/a/57556297/317083

我假设您是因为要调用的功能很重,并且需要将主线程释放到UI。:(

对于类似的任务,我创造了一系列承诺。类似于以下(伪(代码的内容。

let p = new Promise( (resolve, reject) => {
  resolve(true)
})
funcArray.forEach( (func) => { 
    p = p.then(func)
})

这模拟了任务队列。

您还可以写出以下内容的更紧凑,更可读的版本:

async function runArray(fArray) {
    for (let i=0; i<fArray.length; i++) {
        let f = async () => {
            return fArray[i]();
        }
        await f();
    } 
}

请注意后者与前者的代码不同,在本例中,您在提供的数组中运行所有弹性。在第一个示例中,您保持队列工作,只需致电.then(...)

如果您正在寻找相同问题的答案。这就是我最终想到的...

export function concatWalk<T>(observables: Observable<T>[]): Observable<T> {
    const observablesClone = observables.slice(0) as Observable<T>[];
    return iterate(observablesClone);
}
export function iterate<T>(observables: Observable<T>[]): Observable<T> {
    const anElement = observables.shift();
    if (observables.length === 0) {
        return anElement;
    }
    return anElement.pipe(
        concatMap(
            (result) => {
                return iterate(observables);
            }
        )
    );
}

我会这样使用:

private mapChildrenOfNode(sourceNode: TreeNode, trx: number) {
    const childrenCalls$ = sourceNode.childrenNested.map(
        childNodeId => this.convertIdToObjectFetch(childNodeId, trx)
    );
    concatWalk(childrenCalls$);
}

但是一段时间后,我发现异步等待着,并重构了很多,所以现在以上看起来会STH。像这样

private async mapChildrenOfNode(sourceNode: TreeNode, trx: number) {
    const childrenCalls$ = sourceNode.childrenNested.map(
        childNodeId => await this.convertIdToObjectFetch(childNodeId, trx).toPromise()
    );
}

,但大多数情况下我都像这样使用

    async getGraphValues(treeNode: TreeNode, timeSpan, raster: Raster = Raster.MINUTE_15) {
        const x = await this.getAxisValues(treeNode, 'x', timeSpan, raster).toPromise();
        const y = await this.getAxisValues(treeNode, 'y', timeSpan, raster).toPromise();
        const z = await this.getAxisValues(treeNode, 'z', timeSpan, raster).toPromise();
        const w = await this.getAxisValues(treeNode, 'w', timeSpan, raster).toPromise();
        return {x, y, z, w};
    }

或喜欢这个

    async reloadAndMapNodeData(treeNode: TreeNode, timeSpan: TimeSpan) {
        const trx = await this.dataService.transactionBegin().toPromise();
        const refId  = treeNode.reference_object_id;
        await this.loadAndMapStructureObjectData(treeNode, trx).toPromise();
        await this.loadAndMapStructureObjectCollectionData(treeNode, trx).toPromise();
        await this.loadAndMapSankeyNode(treeNode, trx).toPromise();
        await this.dataService.transactionClose(trx).toPromise();
    }

它更干净,更易于阅读。在经常之前,我会有这样的大嵌套呼叫(加上这些嵌套的结构呼叫与其他嵌套本身的调用(

x.pipe(
    map(
        () => y.pipe(
            map(
                () => z.pipe(
...

最新更新