gpt4 book ai didi

angular - 如何等待可选的 Observable

转载 作者:行者123 更新时间:2023-12-04 16:29:34 25 4
gpt4 key购买 nike

在我的 Angular 应用程序中,我进行了可选的 HTTP 调用以检查用户是否存在。根据这次通话的结果,我要么再打一次电话,要么停止处理。如果不求助于 .toPromise(),我如何才能等待在 if block 中进行的调用?

  onSomeEvent() {
const contact: IContact = {
...this.userForm.value
};

let cancelProcessing = false;

if (this.isNewUser()) {
// *** This is optional
this.userService.duplicateUserSearch(contact.email, contact.userName)
.subscribe(result => {
if (result.result !== '') {
cancelProcessing = true;
}
});
}

// *** This statement is hit before the observable completes
if (cancelProcessing) {
return;
}

// *** which means that this runs when it shouldn't
this.userService.updateContact(contact)
.subscribe(res => {
this.activeModal.close(res);
});
}

最佳答案

正如您在问题中所展示的,Observables 的 If/Then 逻辑可能很棘手。关于这个有一个很好的讨论 here .

您已经有了一些在特定条件下可行的答案,我本可以一走了之,将您交给范或杰弗里的能干之手,但我对您对一个答案的评论很感兴趣:“如果我添加更多条件会怎样?”。这引起了我的兴趣,因此我想找到一种基于可观察/功能的模式,如果您以后决定添加额外的条件,它清晰易读并且易于扩展。一个好问题让我认真思考,你肯定做到了。 :)

我尝试将上面链接的文章中建议的模式应用于您的问题,下面的代码是我想出的。正如我在上面对你的原始问题的评论中提到的,我不是 100% 确定你打算在用户不是新用户时更新联系人,但现在我假设你这样做了。免责声明:我没有对此进行严格测试,例如创建 Stackblitz 和创建各种测试用例,尽管这是我通常想要回答此类问题的方式,因此对于以下代码中的任何错误或意外后果,我深表歉意。唉,周末来了。 ;)

在文章的那个模式中,建议通过 if/then 逻辑为所有可能的路径创建分支。我想出了两个主要分支,它们会导致调用 updateContact()。请注意,使用此模式很容易在任何分支中添加 tap() 以在需要时执行其他工作。如果我错过了您想添加的分支,那么添加起来也应该很容易。

这个模式的核心是末尾的 merge() 。这将创建一个合并两个传入的可观察对象。如果其中一个完成,则订阅将执行并运行 updateContact()。在这种情况下,它们永远不会同时完成,因为 isNewUser() 过滤器保证只有一个将处于事件状态,但如果您在其他地方应用此模式,您可能需要添加一个 take(1) 如果您只关心第一个“获胜”的异步。

我还显示订阅和取消订阅,因为我认为这是最佳做法。

onSomeEventSub : Subscription; // component scope variable to add to later unsubscribe with

onSomeEvent() {
const contact: IContact = {
...this.userForm.value
};

// define duplicateUserSearch$ now for easier readability below
const duplicateUserSearch$: Observable<boolean> =
this.userService.duplicateUserSearch(contact.email, contact.userName).pipe(
map(result => (result.result === '')));

// First, create a shareable source for eventual merge of all branches.
// of(0) is completely arbitrary. It would be more interesting to tie
// this to the original event, but that wasn't part of the question. :)
const source$ = of(0).pipe(
share() // same observable will have multiple observers
);

// branch 1 is for when the user is a new user and duplicate logic asserts
const isNewUserAndIsDupe$ = source$.pipe(
filter(() => isNewUser()),
mergeMap(() => duplicateUserSearch$),
filter(res => res)
);

// branch 2 is when the user is NOT a new user
const isNotNewUser$ = source$.pipe(
filter(() => !isNewUser())
);

// and finally the merge that pulls this all together and subscribes
this.onSomeEventSub = merge(isNewUserAndIsDupe$, isNotNewUser$).pipe(
mergeMap(() => this.userService.updateContact(contact))
).subscribe(res => this.activeModal.close(res));

}

ngOnDestroy() {
if (this.onSomeEventSub) this.onSomeEventSub.unsubscribe();
}

关于angular - 如何等待可选的 Observable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53560839/

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