在RxJS主题的订阅回调中,我希望在await
函数上async
。下面是打字稿发布者抱怨说的代码示例:
错误:(131,21)TS2304:找不到名称'await'。
async ngOnInit() {
this.subscriber = dateSubscription.subscribe((date: Date) => {
let dbKey = await this._someService.saveToDatabase(someObject);
// wait for db write to finish before evaluating the next code
// ... some other code here
});
}
通常我在尝试在非async
函数内调用await时会看到这一点。我是否需要进行订阅回调async
或者我是否会犯错?函数saveToDatabase
为async
,并返回一个解析为写入的数据库主键的promise。
答案 0 :(得分:22)
您可以直接将异步签名添加到subscribe
中的匿名函数调用中 this.subscriber = dateSubscription.subscribe(async (date: Date) => {
let dbKey = await this._someService.saveToDatabase(someObject);
// wait for db write to finish before evaluating the next code
// ... some other code here
});
答案 1 :(得分:7)
您无需使用await
,也无需将Promise
转换为Observable
。
这是一个模拟函数saveToDatabase
的示例:
(以及正在使用的Plunkr:https://plnkr.co/edit/7SDLvRS2aTw9gYWdIznS?p=preview)
const { Observable } = Rx;
const saveToDatabase = (date) =>
new Promise(resolve =>
setTimeout(() =>
resolve(`${date} has been saved to the database`),
1000));
const date$ = Observable.of(new Date()).delay(1000);
date$
.do(x => console.log(`date received, trying to save it to database ...`))
.switchMap(date => saveToDatabase(date))
.do(console.log)
.subscribe();
答案 2 :(得分:1)
这是我解决此问题的方法
const title = await new Promise<string>(resolve =>
this.translate.get('MYBOOK-PAGE.PLEASE_REMOVE')
.subscribe(translated => {
resolve(translated)
}));
在这里,我正在做的就是将“可观察的”更改为“承诺”
注意:这里唯一的问题是这是一次演出,即。如果你 订阅后,您将无法再次访问它。适合我,所以分享 在这里。
答案 3 :(得分:1)
也许对此问题已进行了更新。我也有类似的需要等待响应,而不是在Observable实现中使用await
或setTimeout()方法,现在一种更干净的方法是在完成订阅之前使用RxJS内置的interval()
方法
在服务中尝试以下方法:
import { interval } from 'rxjs';
...
// inside your method
const source = interval(100);
source.subscribe(x => {
subject.next(CONNECTIONS_DATA);
subject.complete();
});
return subject;
RxJS文档: https://rxjs-dev.firebaseapp.com/guide/subject#reference-counting
如果有人最近尝试这样做,希望会有所帮助。
答案 4 :(得分:0)
您不能直接await
可观察,但您可await
Promise
。您可以在observables订阅上使用.toPromise()
方法。请考虑以下事项:
async ngOnInit() {
const date = await dateSubscription.toPromise();
let dbKey = await this._someService.saveToDatabase(someObject);
}
当await
承诺dateSubscription
时,您将获得Date
个对象。然后,您可以继续执行下一行,这样可以更顺序地读取代码。
有些人认为角度不会等待ngOnInit
完成,它没有选择权。查看给定JavaScript
here的结果TypeScript
。如您所见,ngOnInit
将调用内部管理和执行底层状态机(生成器)的awaiter。 Angular对此没有任何控制权。它只是想要调用该方法。
答案 5 :(得分:-1)
async ngOnInit() { }
是不正确的签名,因为这是Angular定义OnInit
接口的方式。它应该返回void
:
export interface OnInit { ngOnInit(): void; }
如果您承诺在dateSubscription
之后处理,则可以使用Observable.fromPromise
dateSubscription
.flatMap(x=>
Observable.defer(Observable.fromObservable(this._someService.saveToDatabase(someObject)))
).subscribe()