我使用了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(
...