对可观察的角度订阅 - 仅在请求后才需要价值

发布于 2025-01-23 03:48:38 字数 1673 浏览 0 评论 0原文

我有一个看起来像这样的服务:

export class WebViewService {

  private webViewMessage = new ReplaySubject<any>(1);
  public webViewMessage$ = this.webViewMessage.asObservable();

  public isWebView: boolean = false;
  constructor() {
    this.isWebView = false;

    if (window?.chrome?.webview)
    {
      this.isWebView = true;
    }
   
    window?.chrome?.webview?.addEventListener('message', (event: { data: any; }) => {
      this.webViewMessage.next(event.data);
    });
  }

  public postMessage(message: any) {
    window?.chrome?.webview?.postMessage(message);
  }
}

而且我有一个看起来像这样的组件:

export class BrowserComponent implements OnInit {

  constructor(private webViewService: WebViewService) { }

  subscription!: Subscription;

  ngOnInit(): void {
    this.subscription = this.webViewService.webViewMessage$.subscribe(o => {
      alert(o);
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  onClick() {
    this.webViewService.postMessage("showDialog");
  }
}

当调用onclick()方法时,通过WebViewService发布了一条消息,该消息又在父窗口(窗口表单)中显示出显示一个文件对话框,然后我想知道响应是什么,这将在WebViewMessage $中。我现在在订阅中显示一个警报(),但是将来会有所不同。

问题:当我离开浏览组件然后再次输入时,该警报会弹出最后一个WebViewMessage $,这是我期望的,但不是我想要的。

我可以将OnClick()代码更改为类似的内容:

  onClick() {
    this.webViewService.postMessage("showDialog");
    this.subscription = this.webViewService.webViewMessage$.subscribe(o => {
      alert(o);
      this.subscription.unsubscribe();
    });
  }

但是,一旦我再次单击OnClick()按钮,这将弹出最后一条消息 - 我知道为什么会发生这种情况,但是我无法“等待” postmessage()方法接收响应。但同样,我只希望在此之后收到的消息。WebViewService.PostMessage()已被调用。我该怎么做?

I have a service that looks like this:

export class WebViewService {

  private webViewMessage = new ReplaySubject<any>(1);
  public webViewMessage$ = this.webViewMessage.asObservable();

  public isWebView: boolean = false;
  constructor() {
    this.isWebView = false;

    if (window?.chrome?.webview)
    {
      this.isWebView = true;
    }
   
    window?.chrome?.webview?.addEventListener('message', (event: { data: any; }) => {
      this.webViewMessage.next(event.data);
    });
  }

  public postMessage(message: any) {
    window?.chrome?.webview?.postMessage(message);
  }
}

And I have a component that looks like this:

export class BrowserComponent implements OnInit {

  constructor(private webViewService: WebViewService) { }

  subscription!: Subscription;

  ngOnInit(): void {
    this.subscription = this.webViewService.webViewMessage$.subscribe(o => {
      alert(o);
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  onClick() {
    this.webViewService.postMessage("showDialog");
  }
}

When the onClick() method is called, a message is posted via the webViewService which in turn results in the parent window (a windows form) showing a file dialog and then I want to know what the response is, and that will be in the webViewMessage$. I am showing an alert() now in the subscription but in future, it'll be different.

Problem: when I leave the Browse component and then enter it again, the alert pops up with the last webViewMessage$, which is what I would expect but not what I want.

I can change the onClick() code to something like this:

  onClick() {
    this.webViewService.postMessage("showDialog");
    this.subscription = this.webViewService.webViewMessage$.subscribe(o => {
      alert(o);
      this.subscription.unsubscribe();
    });
  }

However, this pops up a the last message as soon as I click the onClick() button again - I know why this happens, but I have no way to "wait" for postMessage() method to receive a response. But again, I only want the message that has been received AFTER this.webViewService.postMessage() has been called. How would I do this??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

铃予 2025-01-30 03:48:38

制作行为是为了保留发出的最后一个值。这就是为什么创建它时,必须提供默认值。

replayubject是为了保留发出的给定数量的值。创建它时,您必须指定要保留多少值。

而是使用主题,观察者只有在发送值时才会触发,并且不会保留发出的最后一个值。

private webViewMessage = new Subject<any>();

A BehaviorSubject is made to retain the last value emitted. That's why when you create it, you have to provide a default value.

A ReplaySubject is made to retain a given number of values emitted. When creating it, you must specify how many values you wish to retain.

Instead, use a Subject, which observers will trigger only when a value is sent through, and that does not retain the last value emitted.

private webViewMessage = new Subject<any>();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文