如何在Angular 2/4 中启动匿名异步函数?

How to start an anonymous asynchronous function in Angular 2/4?

在我的 Angular 4 组件中,我有一个排序方法。它实际上就像单击 table 的 header 并按该列和 ascending/descending 更改排序顺序一样简单。但是,那里有一个服务调用最终可能会变得非常昂贵,所以我试图使这个调用异步。示例:

sortColumn(): void {
    this.service.someExpensiveBlockingOperation();
    this.sortOrder = !this.sortOrder;
    this.data.sort((a, b) => { ... });
}

我试过搞乱 Promises 和 Observables,以及 Async / Await 但没有成功。我觉得我错过了一些东西,因为 JS 应该是一种 non-blocking,异步驱动的语言。

如果你想要它是异步的,那么就这样做

sortColumn(): void {
    this.service.someExpensiveBlockingOperation().subscribe(result => {
        // Do what you want here 
    });
    this.sortOrder = !this.sortOrder;
    this.data.sort((a, b) => { ... });
}

as JS is supposedly a non-blocking, asynchronous driven language

不,不是。但我们通常 在倾向于异步的环境中使用 它。 JavaScript 基本上就像任何其他语言一样,代码是一步一步同步进行的。 only 关于 JavaScript 本身的异步事情,与我们 运行 它所在的环境相反,是承诺和围绕它们的语法,例如 async/await.

如果你想让你的排序调用相对于触发器是异步的,那么看一下 promises 是对的:

sortColumn(): void {
    this.sortOrder = !this.sortOrder;
    Promise.resolve().then(() => {
        this.service.someExpensiveBlockingOperation();
        this.data.sort((a, b) => { ... });
    });
}

我已将标志翻转放在同步代码中,将其他所有内容放在异步回调中。 then 回调保证被异步调用。

您也可以使用 setTimeout

sortColumn(): void {
    this.sortOrder = !this.sortOrder;
    setTimeout(() => {
        this.service.someExpensiveBlockingOperation();
        this.data.sort((a, b) => { ... });
    }, 0);
}

在兼容 ES2015+ 的环境中,then 回调将比 setTimeout 回调调用得更快,因为 promise 回调 "microtasks" 运行 紧跟在宏任务之后他们预定的地方已经完成,而 setTimeout 回调是一个宏任务。在实践中,它很少相关(但 ,有时)。