英文:
can I call the apis in observable in a certain sequence/order
问题
我正在学习angular
中的Observable
主题。我尝试在Observable
内部调用API,并希望它们按照我指定的顺序运行。
下面是我的组件类代码:
import { HttpClient } from '@angular/common/http';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
@Component({
selector: 'app-flav4',
templateUrl: './flav4.component.html',
styleUrls: ['./flav4.component.css']
})
export class Flav4Component implements OnInit, OnDestroy {
orderStatus!: any;
data!: Observable<any>;
constructor(private httpcli: HttpClient) { }
ngOnInit(): void {
this.data = new Observable(observer => {
this.httpcli.get("http://localhost:9898/api/orderStart", { headers: { "content-type": "application/json" } }).subscribe(data => {
console.warn(data);
this.orderStatus = data;
observer.next(this.orderStatus);
});
this.httpcli.get("http://localhost:9898/api/orderWait", { headers: { "content-type": "application/json" } }).subscribe(data => {
console.warn(data);
this.orderStatus = data;
observer.next(this.orderStatus);
});
this.httpcli.get("http://localhost:9898/api/orderComplete", { headers: { "content-type": "application/json" } }).subscribe(data => {
console.warn(data);
this orderStatus = data;
observer.next(this.orderStatus);
});
});
this.data.subscribe(val => this.orderStatus = val);
}
ngOnDestroy(): void {
}
}
我期望控制台输出为:
{"status": "orderStarted"}
{"status": "orderWaiting"}
{"status": "orderCompleted"}
然而,我得到了以下输出:
{"status": "orderStarted"}
{"status": "orderCompleted"}
{"status": "orderWaiting"}
为了获得所期望的输出,即按照特定的顺序或序列运行API,你应该做以下更改:
你可以使用concatMap
操作符来确保API按照你的顺序运行。例如:
import { concatMap, switchMap } from 'rxjs/operators';
// ...
this.data = new Observable(observer => {
this.httpcli.get("http://localhost:9898/api/orderStart", { headers: { "content-type": "application/json" } }).pipe(
concatMap(data => {
console.warn(data);
this.orderStatus = data;
observer.next(this.orderStatus);
return this.httpcli.get("http://localhost:9898/api/orderWait", { headers: { "content-type": "application/json" });
}),
concatMap(data => {
console.warn(data);
this.orderStatus = data;
observer.next(this.orderStatus);
return this.httpcli.get("http://localhost:9898/api/orderComplete", { headers: { "content-type": "application/json" });
})
).subscribe(data => {
console.warn(data);
this.orderStatus = data;
observer.next(this.orderStatus);
});
});
// ...
这样,你可以确保API按照你的指定顺序运行。
英文:
I am learning angular
Observable
topic. I was trying to call apis inside Observable and hoping that they will run in an order in which I have stated them.
Below is my component class code:
import { HttpClient } from '@angular/common/http';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
@Component({
selector: 'app-flav4',
templateUrl: './flav4.component.html',
styleUrls: ['./flav4.component.css']
})
export class Flav4Component implements OnInit, OnDestroy {
orderStatus!: any;
data!: Observable<any>;
constructor(private httpcli: HttpClient) { }
ngOnInit(): void {
this.data = new Observable(observer => {
this.httpcli.get("http://localhost:9898/api/orderStart", { headers: { "content-type": "application/json" } }).subscribe(data => {
console.warn(data);
this.orderStatus = data;
observer.next(this.orderStatus);
});
this.httpcli.get("http://localhost:9898/api/orderWait", { headers: { "content-type": "application/json" } }).subscribe(data => {
console.warn(data);
this.orderStatus = data;
observer.next(this.orderStatus);
});
this.httpcli.get("http://localhost:9898/api/orderComplete", { headers: { "content-type": "application/json" } }).subscribe(data => {
console.warn(data);
this.orderStatus = data;
observer.next(this.orderStatus);
});
});
this.data.subscribe(val => this.orderStatus = val);
}
ngOnDestroy(): void {
}
}
I was expecting console output to be
{"status": "orderStarted"}
{"status": "orderWaiting"}
{"status": "orderCompleted"}
However I got below output
{"status": "orderStarted"}
{"status": "orderCompleted"}
{"status": "orderWaiting"}
What should I change in this code in order to get desired output i.e to run APIs in a certain order or sequence.
答案1
得分: 1
这是正常行为,因为HTTP请求是异步的。
您可以尝试使用mergeMap
,也被称为RxJS库中的flatmap
,来链接它们。我建议您也查看一下行为。
参考以下示例:
import { HttpClient } from '@angular/common/http';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
@Component({
selector: 'app-flav4',
templateUrl: './flav4.component.html',
styleUrls: ['./flav4.component.css']
})
export class Flav4Component implements OnInit, OnDestroy {
orderStatus!: any;
data!: Observable<any>;
constructor(private httpcli: HttpClient) { }
ngOnInit(): void {
this.data = this.httpcli.get("http://localhost:9898/api/orderStart", { headers: { "content-type": "application/json" } }).pipe(
mergeMap(orderStart => {
console.warn(orderStart);
this.orderStatus = orderStart;
return this.httpcli.get("http://localhost:9898/api/orderWait", { headers: { "content-type": "application/json" } });
}),
mergeMap(orderWait => {
console.warn(orderWait);
this.orderStatus = orderWait;
return this.httpcli.get("http://localhost:9898/api/orderComplete", { headers: { "content-type": "application/json" } });
})
);
this.data.subscribe(orderComplete => {
console.warn(orderComplete);
this.orderStatus = orderComplete;
});
}
ngOnDestroy(): void {
}
}
这是您提供的代码的中文翻译。
英文:
This is normal behaviour as HTTP requests are asynchronous.
You can try chaining them with mergeMap
also known as flatmap from RxJS library. I suggest you take a look at the behaviours as well.
Something like this as reference
import { HttpClient } from '@angular/common/http';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
@Component({
selector: 'app-flav4',
templateUrl: './flav4.component.html',
styleUrls: ['./flav4.component.css']
})
export class Flav4Component implements OnInit, OnDestroy {
orderStatus!: any;
data!: Observable<any>;
constructor(private httpcli: HttpClient) { }
ngOnInit(): void {
this.data = this.httpcli.get("http://localhost:9898/api/orderStart", { headers: { "content-type": "application/json" } }).pipe(
mergeMap(orderStart => {
console.warn(orderStart);
this.orderStatus = orderStart;
return this.httpcli.get("http://localhost:9898/api/orderWait", { headers: { "content-type": "application/json" } });
}),
mergeMap(orderWait => {
console.warn(orderWait);
this.orderStatus = orderWait;
return this.httpcli.get("http://localhost:9898/api/orderComplete", { headers: { "content-type": "application/json" } });
})
);
this.data.subscribe(orderComplete => {
console.warn(orderComplete);
this.orderStatus = orderComplete;
});
}
ngOnDestroy(): void {
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论