【问题标题】:TypeScript and Angular, order of execution in thisTypeScript 和 Angular,执行顺序在此
【发布时间】:2019-10-19 10:58:03
【问题描述】:

我在 Angular 应用程序中有以下代码,html 看起来像这样。

<ng-multiselect-dropdown
    (onSelect)="onSubstringSelect($event)">
</ng-multiselect-dropdown>

onSubstringSelect 在组件的 .ts 部分中:

onSubstringSelect(item: any) {
    const dataPois = this.getPois(data);
    alert("2nd alert " + dataPois);
    // etc
}

getPois(data): any[] {
    this.api.getPois(data).subscribe((result: any) => {
        alert("1st alert");
        return result.pois;
        }
    }, (error: any) => {
        console.error('error', error);
        return {};
    });

    return null;
}

我希望我首先拥有alert("1st alert");,然后是alert("2nd alert " + dataPois);,但该警报首先执行。为什么?

【问题讨论】:

  • onSubstringSelect 在哪里调用?
  • 从一个 Angular 组件,我将编辑问题
  • 在哪里调用 onSubstringSelect 并不重要。订阅是异步执行的。

标签: javascript typescript rxjs


【解决方案1】:

你不知道什么时候会返回异步数据。在这种情况下,答案是在执行alert("2nd alert " + dataPois); 之后。

【讨论】:

  • 有没有办法强制返回的数据继续我的代码?
  • 我认为alert("2nd alert " + dataPois); 将 dataPois 返回为未定义
  • 我会尝试:onSubstringSelect(item: any) { getPois.subscribe( (result: any) =&gt; { alert("2nd alert " + dataPois); return result.pois; }, (error: any) =&gt; { console.error('error', error); return {}; }); } getPois(data) { return this.api.getPois(data); }
  • 如果你想显示dataPois,你必须在订阅中运行alert("2nd alert " + dataPois);
【解决方案2】:

这是因为 Rx 流是异步的。当您设置流时,它确实设置了它;但是直到有东西在听这个之前什么都没有运行。在 Rx 世界中,这称为subscribing

当您使用stream$ | async 将您的信息流移交给AsyncPipe 时;它将订阅并且设置流中的所有功能将按顺序开始运行。

起初这似乎违反直觉,但实际上很有意义。如果您希望 console.log 按您希望的顺序运行,请按顺序添加 tap() operators 或重新定义您的流以符合您的期望。

当你这样做时:

function A() {
    const stream$ = this.http.get('my-stream-url').pipe(
            tap(() => { console.log('stream is live!') })
        )
    console.log('But this will show up first, because nothing is listening to the stream$ yet!')
    return stream$
}

您可以看到流将如何保持停滞,直到有人通过subscribing 开始收听它。

【讨论】:

  • 那么在获取 ajax 调用的数据后,如何继续使用我的代码呢?我不知道如何“等待”来自 API 的数据,然后继续在我的代码中做事
  • 响应式编程的诀窍在于,您将“所有需要发生的事情”编写为声明性流。因此,您可以将其写为tap() 副作用,并在实际订阅之前将 Observable 尽可能地向下推。本着同样的精神,您可能更容易不手动subscribe(),而是让 Angular 为您处理它。查看 angular.io 上的 AsyncPipe 示例。
猜你喜欢
  • 2017-12-25
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
  • 2017-09-04
  • 2019-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多