【问题标题】:Cancel promise api request in angular 8 when enter to function进入功能时取消角度8中的promise api请求
【发布时间】:2020-07-13 12:09:31
【问题描述】:

我有点卡住了。 我有一个带有用户名输入的表单,它必须是 uniq。 所以我绑定到这个输入一个类,该类触发对服务器的调用并检查输入状态(正在使用或未使用)。 我用超时包装了所有东西(让用户写信然后触发请求)。

代码:

static serverUniqueUserNameExists(authService: AuthService, timeout = 1500): AsyncValidatorFn {
    return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
        return new Observable((observer: Observer<ValidationErrors | null>) => {
            if (control.value.length == 0) {
                observer.next(null)
                observer.complete()
            } else {
                const clearTimer = setTimeout(async () => {
                    const res = await this.getUserNameStatus(authService, control)
                    if (res.status >= '400') {
                        observer.next({ error: true, serverError: true })
                    } else {
                        if (res.data.userExists) {
                            observer.next({ error: true, userNameAlreadyExist: true })
                        } else {
                            observer.next(null)
                            clearTimeout(clearTimer)
                        }
                    }
                    observer.complete()
                }, timeout)
            }
        })
    }
}

但是当我查看网络时,我发现对于我输入的每个字母,我都会向服务器发出一个请求。

我需要以某种方式取消所有先前已触发的 api 调用并仅触发 last 请求。

找不到任何方法。

有人帮忙吗?

【问题讨论】:

    标签: javascript angular ecmascript-6 promise angular-reactive-forms


    【解决方案1】:

    您可以创建一个简单的isFetching 状态,随时返回 请求正在进行中。建议您在页面侧进行。采样时间在文本输入中添加denounce,使其不会随每个字符更新。

    let isFetching = false
    static serverUniqueUserNameExists(authService: AuthService, timeout = 1500): AsyncValidatorFn {
        return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
            if(isFetching) return Promise.resolve(null); // return from here
            return new Observable((observer: Observer<ValidationErrors | null>) => {
                if (control.value.length == 0) {
                    observer.next(null)
                    observer.complete()
                } else {
                    const clearTimer = setTimeout(async () => {
                        /// code here
                        isFetching = false;
                        observer.complete()
                    }, timeout)
                }
            })
        }
    }
    

    // 去抖样本:

    results$: Observable
        subject = new Subject()
        constructor(private httpClient: HttpClient) {}
        ngOnInit() {
            this.results$ = this.subject.pipe(
                debounce(() => Rx.Observable.interval(1000)),
                map(searchText => this.httpClient.get("/api/search?q=" + searchText))
            )
        }
    

    更多: https://blog.bitsrc.io/3-ways-to-debounce-http-requests-in-angular-c407eb165ada

    【讨论】:

    • ok 看起来不错,但是你以什么方式声明 isFetching = true ?
    • 但是这样我总是触发第一个呼叫而没有任何方法可以取消它,不是吗?如果我得到你这是非常好的方法,但不会在连续输入中触发 1 个请求。并且在接下来的 1500 毫秒内它不会触发任何东西,因为我们在第一次调用后将 isFatching 初始化为 true
    猜你喜欢
    • 2015-11-21
    • 2023-04-05
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    相关资源
    最近更新 更多