Angular:在循环中执行连续的 HTTP-Delete 不起作用

Posted

技术标签:

【中文标题】Angular:在循环中执行连续的 HTTP-Delete 不起作用【英文标题】:Angular : Perfoming successive HTTP-Delete in a loop doesn't work 【发布时间】:2021-08-09 14:08:30 【问题描述】:

我正在开发一个使用 Angular CRUD 操作的网站,但我很难对我的数据库执行连续删除。

我在一个名为 « this.checkedLogs » 的数组中恢复了需要从数据库中删除的 ID(这部分确实有效)。 然后,当我单击一个按钮时,我会调用一个用于执行这些删除的函数:« onModalConfirm »。 问题是它运行得太快了,以至于我的迭代器没有时间改变它的值和要从我的数组中删除的实际 ID,以至于函数已经循环了。 此外,在循环结束时,条件 « if (this.checkedLogs.length == 0) » 不成立,这表明它运行得如此之快。

我正在考虑添加等待功能,但我不知道这是否符合良好的做法。 我仍然是 Angular 的初学者,对 Observable 周围的一切还不太熟悉。

这是我的 service.ts :
deleteLogsByID(id: number): Observable<any> 
    return this._httpClient.delete(`$API_BASE_URL/delete/id/$id`, responseType: 'text');
  
这是我的 component.ts:
deleteLogsByID(id: number): void 
        this.logsSubscription = this.LogsService.deleteLogsByID(id).subscribe(
            (data: any) => 
                this.deleteMessage = data;
            ,
            (error: HttpErrorResponse) => 
                this.showSpinner = false;
                this.error = error.message;
                this.showError = true;
            
        );
    

onModalConfirm() 
        /** Getting the length of my array by updating this.selectionAmount */
        this.updateSelectionAmount();

        /** If it’s not empty */
        if (this.selectionAmount != 0) 

            let iterator = this.checkedLogs.values();
            for (let index = 0; index < this.selectionAmount; index++) 
                /** Getting the id of the iterator */
                let id: number = iterator.next().value;

                /** Calling my delete function */
                this.deleteLogsByID(id);


                /** Removing the id from the array */
                this.checkedLogs.splice(id, 1);
            

            /** When everything is done, reload the page */
            if (this.checkedLogs.length == 0)
                window.location.reload()
        
    

updateSelectionAmount() 
        this.selectionAmount = this.selection.selected.length;
    
html 代码在我的问题中似乎并不重要,但这是我的删除函数的后端代码(运行良好):
@ApiOperation(value = "Delete a logs by its id", produces = "application/json")
@PreAuthorize("hasRole('MODERATOR') or hasRole('ADMIN')")
@DeleteMapping("/delete/id/id")
public ResponseEntity<String> deleteLogsById(@PathVariable Integer id) 

    Integer idRemoved = logsService.deleteLogsById(id);

    if (idRemoved == 0)
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);

    String responseReturn = "Logs removed with id " + id;

    return new ResponseEntity<>(responseReturn, HttpStatus.OK);

提前致谢!

【问题讨论】:

您是否可以扩展您的后端以能够处理接受 Id 的集合以及单数 Id?这可能会更健壮一些,并且不会产生那么多的网络请求。 我明白你的意思,这可能是一个不错的选择!如果我的理解正确,我需要创建一个新端点,通过将数组传递到请求正文中来执行多次删除? 【参考方案1】:

是的,你没看错,for循环执行得很快,它调用了一堆请求,并在请求执行之前拼接了checkedLogs。不知道你所有的应用程序逻辑,但我建议使用好的旧回调来使删除操作有点顺序。 onModalConfirm 类似于:

onModalConfirm() 
    /** Getting the length of my array by updating this.selectionAmount */
    this.updateSelectionAmount();

    /** If it’s not empty */
    if (this.selectionAmount != 0) 
        let iterator = this.checkedLogs.values();
        const callDelete = () => 
            let id: number = iterator.next().value;
            const continueFn = (id) => 
                if (id !== undefined) 
                    callDelete();
                
            
            if (id !== undefined) 
                this.deleteLogsByID(id, continueFn);
            
        
        callDelete();
    

而 deleteLogsByID 将是:

deleteLogsByID(id: number, callbackFn: (id: number) => void): void 
    this.logsSubscription = this.LogsService.deleteLogsByID(id).subscribe(
        (data: any) => 
            this.deleteMessage = data;
            callbackFn(id)
        ,
        (error: HttpErrorResponse) => 
            this.showSpinner = false;
            this.error = error.message;
            this.showError = true;
            callbackFn(id);
        
    );

【讨论】:

嗨@MRsa,感谢您的回复!我理解回调的逻辑,但我不熟悉这个语法:“const callDelete=()=> ...”我会搜索一下。此外,我测试了您编写的代码,似乎 deletelogsByID(...) 的调用次数比它应该调用的次数多两次。但由于我不熟悉语法我无法解决它 const fnName = () => 与(仅绑定 this 不同)几乎相同 const fnName = function () 无论如何我认为 array.splice 中的问题 - 参数是错误的(第一个参数应该是开始 postiton 而不是 Id 值)我改变了答案,只需检查循环结束时的迭代器是否返回“未定义”或其他内容并更改代码。让遍历数组的迭代器在同一个函数(拼接)中也发生变化是个坏主意

以上是关于Angular:在循环中执行连续的 HTTP-Delete 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Angular 8:无法实例化循环依赖 - ActivatedRoute

Handler Runnable 自动执行 循环 连续 延时

在 php 中运行仅在尚未运行时才运行的连续循环的最佳方法是啥?

1106 数组

angular在遍历数组之后如何给第一个元素加默认

如何在 angular2 中进行连续的 http api 调用?