Angular 如何正确使用exhaustMap-如何在发送另一个请求之前等待服务调用返回
我使用一个按钮来Angular 如何正确使用exhaustMap-如何在发送另一个请求之前等待服务调用返回,angular,rxjs,angular7,Angular,Rxjs,Angular7,我使用一个按钮来initialiseGrid()。在通话过程中,如果不禁用按钮,我希望等待第一个响应返回,然后触发第二个请求,或者(即使触发多个请求)按照请求发生的确切顺序处理响应。实际上,我尝试使用一些rxjs操作符而不是map,但我很确定我没有正确使用它们 于2020年7月20日更新: 我想排气图是正确的操作员使用。我应该如何在query或fetch方法中使用它 请在下面找到我的代码: APs.service.ts public query(token: string, tableName:
initialiseGrid()
。在通话过程中,如果不禁用按钮,我希望等待第一个响应返回,然后触发第二个请求,或者(即使触发多个请求)按照请求发生的确切顺序处理响应。实际上,我尝试使用一些rxjs操作符而不是map
,但我很确定我没有正确使用它们
于2020年7月20日更新:
我想排气图是正确的操作员使用。我应该如何在query
或fetch
方法中使用它
请在下面找到我的代码:
APs.service.ts
public query(token: string, tableName: string, state: any): void {
console.log("state in query", state);
this.fetch(token, tableName, state)
.subscribe((x: any) => {
console.log("response data", this.data);
super.next(x);
this.isLoading = false;
this.mediatorService.sendMessage("APsRefreshed");
},
(err: any) => {
console.log("err", err);
this.isLoading = false;
}
);
}
public fetch(token: string, tableName: string, state: any): Observable<any> {
let queryStr = `${toODataString(state)}&$count=true`;
queryStr = queryStr.replace(/('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig, function (x) {
return x.substring(1, x.length - 1);
});
queryStr = queryStr.replace(/substringof\((.+),(.*?)\)/, "contains($2,$1)");
const regex = /T00:00:00\.000Z/gi;
const noTimeZoneQueryStr = queryStr.replace(regex, '');
let fetchCallResult = this.http
.get(`${this.BASE_URL}` + `/` + token + `${tableName}&${noTimeZoneQueryStr}`)
.pipe(
map((response: any) => ((<any>this.data) = {
data: response['value'],
total: /*response['value'].length*/parseInt(response['@odata.count'], 10)
}
)),
//tap(() => this.isLoading = false)
);
return fetchCallResult;
}
APs.template.html
<kendo-grid #gridView
[data]="gridViewAPs | async"
[loading]="APsService.isLoading"
...
>
提前谢谢。当我需要控制执行顺序,特别是http调用时,我使用一个高阶映射操作符
this.btnCLick$ // 1. That's your button click stream
.pipe(
map(() => ({token, tableName, state})), // 2. Map all your inputs into one input object from where ever you want
concatMap(({token, tableName, state}) => { // 3. This operator will wait for the previous call to complete to make the next call (like a Queue)
let queryStr = `${this.toODataString(state)}&$count=true`;
queryStr = queryStr
.replace(/('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig,
function (x) {
return x.substring(1, x.length - 1);
}
);
queryStr = queryStr.replace(/substringof\((.+),(.*?)\)/, "contains($2,$1)");
const regex = /T00:00:00\.000Z/gi;
const noTimeZoneQueryStr = queryStr.replace(regex, '');
return this.http // 4. This part will make the http calls based on your query
.get(`${this.BASE_URL}` + `/` + token + `${tableName}&${noTimeZoneQueryStr}`)
.pipe(
map((response: any) => ({
data: response['value'],
total: /*response['value'].length*/parseInt(response['@odata.count'], 10)
})
),
//tap(() => this.isLoading = false)
);
})
)
.subscribe(({data, total}) => { // 5. ***When each http call comes back with a response, the subscription will be called
console.log("response data", data);
super.next({data, total});
this.isLoading = false;
this.mediatorService.sendMessage("APsRefreshed");
},
(err: any) => {
console.log("err", err);
this.isLoading = false;
}
);
使用is实现,您不必担心禁用按钮…我在这里只能看到一个http调用,第二个调用应该在哪里?没错。我是指同一服务的第二次(第三次、第四次等)呼叫。谢谢您的回答。我试试看。按钮位于另一个组件中。因此,我无法直接访问按钮。如上所示,initialiseGrid()在ngOnInit()中调用,网格数据源绑定到服务。所以,我不能使用这个.btnCLick$.pipe
this.btnCLick$ // 1. That's your button click stream
.pipe(
map(() => ({token, tableName, state})), // 2. Map all your inputs into one input object from where ever you want
concatMap(({token, tableName, state}) => { // 3. This operator will wait for the previous call to complete to make the next call (like a Queue)
let queryStr = `${this.toODataString(state)}&$count=true`;
queryStr = queryStr
.replace(/('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig,
function (x) {
return x.substring(1, x.length - 1);
}
);
queryStr = queryStr.replace(/substringof\((.+),(.*?)\)/, "contains($2,$1)");
const regex = /T00:00:00\.000Z/gi;
const noTimeZoneQueryStr = queryStr.replace(regex, '');
return this.http // 4. This part will make the http calls based on your query
.get(`${this.BASE_URL}` + `/` + token + `${tableName}&${noTimeZoneQueryStr}`)
.pipe(
map((response: any) => ({
data: response['value'],
total: /*response['value'].length*/parseInt(response['@odata.count'], 10)
})
),
//tap(() => this.isLoading = false)
);
})
)
.subscribe(({data, total}) => { // 5. ***When each http call comes back with a response, the subscription will be called
console.log("response data", data);
super.next({data, total});
this.isLoading = false;
this.mediatorService.sendMessage("APsRefreshed");
},
(err: any) => {
console.log("err", err);
this.isLoading = false;
}
);