将异步函数转换为 RxJs Observable

Tot*_*Tot 3 observable async-await rxjs typescript angular

为了防止编写一定量的代码,比如这个例子:

\n
    ...\n    public getDataSet() : Observable<any>\n    {\n        return new Observable(observer => {\n            if (this.dataset === undefined) {\n                this.get().subscribe(data => {\n                    this.dataset = new DataSet(data) ;\n                    observer.next(this.dataset)\n                    observer.complete() ;\n                }) ;\n            }\n            else {\n                observer.next(this.dataset)\n                observer.complete() ;\n            }\n        }) ;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

我想使用async/await功能,但仍然返回一个 Observable 以在使用异步数据收集服务时保持一致。

\n

因此根据 RxJs 的文档,我应该使用from()运算符。\n https://www.learnrxjs.io/learn-rxjs/operators/creation/from

\n

这是我尝试实现的(看起来更简洁):

\n
import { Observable, from } from \'rxjs\' ;\n...\n        return from(async () => { // \xe2\x9c\x98 error\n            if (this.dataset === undefined) this.dataset = new DataSet(await this.get().toPromise()) ;\n            return this.dataset ;\n        }) ;\n
Run Code Online (Sandbox Code Playgroud)\n

然而,TypeScript 不识别async () => {}ObservableInput,但它确实识别这个:

\n
import { Observable, from } from \'rxjs\' ;\n...\n        return from(new Promise((resolve) => { // \xe2\x9c\x94 valid\n            if (this.dataset === undefined) {\n                this.get().toPromise().then(data => {\n                    this.dataset = new DataSet(data) ;\n                    resolve(this.dataset) ;\n                }) ;\n            }\n            else resolve(this.dataset) ;\n        })) ;\n
Run Code Online (Sandbox Code Playgroud)\n

不过,JavaScript 的async关键字使函数始终返回 Promise。

\n
console.log((async () => {}) ())\n// Promise {}\n
Run Code Online (Sandbox Code Playgroud)\n

有没有办法让from()RxJs 运算符接受异步承诺?

\n

rit*_*taj 11

异步函数在调用时返回一个承诺,在此之前它只是一个函数。

function fromAsyncFunction(): Observable<number> {
    return from((async () => {
      return 1;
    })()); // Call it
}
Run Code Online (Sandbox Code Playgroud)