我正在尝试使用do statment返回一个Observable。 由于某种原因,不会调用do语句。 任何帮助都将得到满足:
public addTarget(video: VideoFile, language?: Language): Observable<Language> {
if (!this.isTargetCollectionDeclared(video)) {
video.metadata = video.metadata || <BaseVideoData>{};
video.metadata.to = [];
}
let wasLanguageProvided = language != null;
if (wasLanguageProvided) {
video.metadata.to.push(language);
return Observable.of(language);
}
return this._getDefaultFromAvilableLanguages(video)
.do(languageOrNull => {
// code is not reaching her
if (languageOrNull != null) {
video.metadata.to.push(languageOrNull)
}
})
}
答案 0 :(得分:2)
Observable是懒惰的,就像函数一样。除非你订阅它们,否则它们不会运行,类似于在你打电话之前函数如何执行。
传递给.do
的回调将在observable被触发后执行,只有在您订阅它之后才会发生。
答案 1 :(得分:0)
仅在异步内部video
函数发出值后才在函数内创建的.do()
运算符内修改输入参数_getDefaultFromAvilableLanguages
非常臭。
这很可能导致在视频对象上出现的语言与预期时刻内的语言难以调试竞争条件。我建议你重构一下这个更纯粹的并返回一个更新的VideoFile:
function enrichVideoWithLanguage(video: VideoFile, language?: Language): Observable<VideoFile> {
// make sure the metadata object is in the expected state
if (!this.isTargetCollectionDeclared(video)) {
video.metadata = video.metadata || <BaseVideoData>{};
video.metadata.to = [];
}
return Observable.of(video)
.mergeMap(
(video) => {
if(language) {
return Observable.of(language)
.toArray();
}
return this._getDefaultFromAvilableLanguages(video)
.filter(lang => lang != null)
.toArray()
},
(video, languages: Language[]) => {
// we used toArray to only modify the video object once
languages.forEach(lang => video.metadata.to.push(language));
return video;
}
);
}
这仍然有点臭,因为原始输入VideoFile将在此函数中被修改,但至少可以帮助您确保enrichVideoWithLanguage
发出的videoFile将包含您在发出后直接期望的语言值。