gpt4 book ai didi

javascript - 如何在 Angular 6 中取消 http 请求?

转载 作者:太空狗 更新时间:2023-10-29 17:51:09 38 4
gpt4 key购买 nike

我有一个包含三个组件的页面:1. 产品列表组件,获取一些产品作为输入并显示它们。2. 显示一些过滤器列表的过滤器组件,即(大小,颜色,...)并显示添加的过滤器。3.Main组件即根组件

假设用户添加了 1 个过滤器,该过滤器会触发一个 http 请求以获取新的过滤产品,并且在请求待处理时他删除了添加的过滤器,该过滤器会触发另一个 http 请求以获取所有产品 如何取消第一个请求,使我们不显示过滤后的产品? 这是我的代码:

class FiltersService {
private _filters: any[];

get filters() {
return this._filters;
}
addFilter(filter) {
this._filters.push(filter);
}

removeFilter(filter) {
// Remove filter logic ...
}

}

class DataService_ {
constructor(private http: HttpClient) {

}

getProducts(filters) {
return this.http.post<any[]>('api/get-products', filters)
}

}


@Component({
selector: 'app-main',
template: `
<div>
<app-filters [filtersChanged]="onFiltersChange()"></app-filters>
<app-products-list [products]="products"> </app-products-list>
</div>
`
})
class MainComponent {
products: any[];

constructor(private dataService: DataService_, private filtersService: FiltersService) {

}

ngOnInit() {
this.setProducts()
}

setProducts() {
let filters = this.filtersService.filters;
this.dataService.getProducts(filters)
.subscribe(products => this.products = products)
}

onFiltersChange() {
this.setProducts();
}
}
@Component({
selector: 'app-filters',
template: `
<div>
Filters :
<ul>
<li *ngFor="let filter of filters" (click)="addFilter(filter)"> {{ filter.name }}</li>
</ul>

<hr>
Added Filters:
<ul>
<li *ngFor="let filter of filtersService.filters"> {{ filter.name }} <button (click)="removeFilter(filter)"> Remove</button></li>
</ul>
</div>

`
})
class FiltersComponent {
filters = [{ name: 'L', tag: 'size' }, { name: 'M', tag: 'size' }, { name: 'White', tag: 'colour' }, { name: 'Black', tag: 'colour' }]
@Output() filtersChanged = new EventEmitter()
constructor(public filtersService: FiltersService) {

}

addFilter(filter) {
const isAdded = this.filtersService.filters.find(x => x.name === filter.name);
if (isAdded) return;
this.filtersService.addFilter(filter);
this.filtersChanged.emit()
}

removeFilter(filter) {
this.filtersService.remove(filter);
this.filtersChanged.emit()
}

}

@Component({
selector: 'app-products-list',
template: `
<div>
<h1>Products</h1>
<ul *ngIf="products.length">
<li *ngFor="let product of products">
{{product.name }}
</li>
</ul>
</div>
`
})
class ProductsListComponent {
@Input() products
constructor() {
}

}

最佳答案

长话短说:

处理此类情况的最简单方法是使用 switchMap 运算符。这样做的目的是在新事件出现时立即取消内部订阅。

一个实现是:

class MainComponent {
products: any[];
private _filters$ = new Subject();

constructor(private dataService: DataService_, private filtersService: FiltersService) {

}

ngOnInit() {
this.setProducts()
}

setProducts() {
this._filters$
.switchMap((filters)=> this.dataService.getProducts(filters)) // or .let(switchMap...) if you are using rxjs >5.5
.subscribe(products => this.products = products);
}

onFiltersChange() {
this._filters$.next(this.filtersService.filters);
}
}

长话短说:

这里发生的是:当您更改过滤器时,将触发 onFilterChange。然后,您通过 _filters$ 主题(主题几乎与 EventEmitter 相同)发出最新的过滤器(在 this.filtersService.filters 内)。

及时回到组件初始化期间,ngOnInit 方法调用了 setProducts,它订阅了 _filters$ 主题以用于 future 事件(此时没有发生)。当事件到达 _filters$ 时,我们会触发数据服务的 getProducts 方法,将事件中包含的过滤器传递给它。我们将在此行等待,直到 http 调用完成。一旦完成,http 调用的结果将被分配给组件的产品。

如果在我们等待 http 响应返回时,onFiltersChange 再次被触发,那么一个新事件将到达 switchMap 并且它将取消之前的 http 请求,以便它可以处理新事件。

这是一种非常强大的方法,因为更改单个运算符,您可以轻松更改应用程序的行为。例如,将 switchMap 更改为 concatMap 将使请求等待前一个请求完成(将连续发生)。将其更改为 flatMap 将具有与您发布的原始代码相同的行为(http 请求将在过滤器更改后立即发生,不影响以前的请求,响应顺序将不可预测)等等。

关于javascript - 如何在 Angular 6 中取消 http 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52096111/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com