如何将我的承诺更改为可观察的?
How to change my promise to an observable?
我有一个带有 selectedLanguage 变量的服务,但我得到的是空值而不是实际值
data: any = {};
selectedLanguage = 'en';
constructor(private http: HttpClient, private storage: Storage) {
}
async use(lang: string): Promise<{}> {
lang = lang ? lang : await this.storage.get('lang');
return new Promise<{}>((resolve) => {
const langPath = `assets/i18n/${lang || 'en'}.json`;
this.selectedLanguage = lang;
this.storage.set('lang', this.selectedLanguage);
this.http.get<{}>(langPath).subscribe(
translation => {
this.data = Object.assign({}, translation || {});
return resolve(this.data);
},
() => {
this.data = {};
return resolve(this.data);
}
);
});
}
get(): string {
return this.selectedLanguage;
}
}
在 component.ts 文件中我使用了它,但不是很好
export class LoginComponent implements OnInit {
imgError = false;
loginForm: FormGroup;
selectedLanguage: string;
constructor(
public storage: Storage,
private translateService: TranslateService,
private alertController: AlertController,
private translate: TranslatePipe
) { }
ngOnInit() {
this.selectedLanguage = this.translateService.selectedLanguage;
如何将 selectedLanguage 用作可观察对象而不获取空值?
只需声明一个 return 可观察的方法。在您的 ngOnInit() 中,调用此方法和 onSubscription 您可以获得该值。方法执行完成后 return 可观察值。我给了一个示例代码。您可以查看此 link 以获取更多信息。
get(langObtained): Observable<String> {
let lang= langObtained;
return of(lang);
}
ngOninit(){
this.get('hi').subscribe(response=>{
//use the response
});
}
下面是一些如何使用 observables 设置语言的示例
setLang(lang: string): Observable<void> {
return fromPromise(this.storage.get('lang')).pipe(flatMap((lang) => {
const langPath = `assets/i18n/${lang || 'en'}.json`;
return this.http.get<{}>(langPath)
}), map(data => {
return ...doSomeDataMapping
}), tap((result) => {
this.data = result;
this.selectedLanguage = lang
}))
}
tap
部分仅在您确实需要有状态服务时才需要。
如果您需要对所选语言字段进行异步 getter,您的点击将如下所示:
tap((result) => {
this.data$.next(result);
this.selectedLanguage$.next(lang)
})
你需要:
private data$ = new BehaviorSubject(initialValue);
private selectedLanguage$ = new BehaviorSubject(initialValue);
在顶部。
那么 getter 将是
getSelectedLanguage$(): Observable<string> {
return this.selectedLanguage$;
}
在组件中调用
this.selectedLanguage$ = this.translateService.getSelectedLanguage$();
并与视图中的 async
管道一起使用
您可以创建一个新的 Observable
观察者接收您的 Promise
的值。
const { Observable } = rxjs;
const promise$ = new Promise(resolve => resolve('Success!'))
const observable$ = new Observable(observer => promise$.then(value => observer.next(value)))
observable$.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
一步一步:
创建Promise
,值Success!
直接为resolved
。还创建了一个 Observable
并且 observer-function
的主体侦听 Promise
.
的值
虽然 Promise
在创建 Observable 之前设置和解析,但为什么我们得到 value
?
Promises
没有同步处理。他们是microtasks
。这些在 makrotasks
之后处理。 RxJS 默认使用 Scheduler 来处理通过其 pipes/operators/functions 的每个值。默认调度程序(您可以在 link 的底部阅读它)是一个 asyncScheduler
,它是某种内部某种 setTimeout
机制,因此是一个 makrotask
.
总和:
Observable
接收 Promise
的值,因为它是在 Promise
值之前处理的。
这是一个复杂的话题。 mikro-
和 markotask
与 JavaScript Event Queue
相关。这个 youtube video 向我解释得很好。
我有一个带有 selectedLanguage 变量的服务,但我得到的是空值而不是实际值
data: any = {};
selectedLanguage = 'en';
constructor(private http: HttpClient, private storage: Storage) {
}
async use(lang: string): Promise<{}> {
lang = lang ? lang : await this.storage.get('lang');
return new Promise<{}>((resolve) => {
const langPath = `assets/i18n/${lang || 'en'}.json`;
this.selectedLanguage = lang;
this.storage.set('lang', this.selectedLanguage);
this.http.get<{}>(langPath).subscribe(
translation => {
this.data = Object.assign({}, translation || {});
return resolve(this.data);
},
() => {
this.data = {};
return resolve(this.data);
}
);
});
}
get(): string {
return this.selectedLanguage;
}
}
在 component.ts 文件中我使用了它,但不是很好
export class LoginComponent implements OnInit {
imgError = false;
loginForm: FormGroup;
selectedLanguage: string;
constructor(
public storage: Storage,
private translateService: TranslateService,
private alertController: AlertController,
private translate: TranslatePipe
) { }
ngOnInit() {
this.selectedLanguage = this.translateService.selectedLanguage;
如何将 selectedLanguage 用作可观察对象而不获取空值?
只需声明一个 return 可观察的方法。在您的 ngOnInit() 中,调用此方法和 onSubscription 您可以获得该值。方法执行完成后 return 可观察值。我给了一个示例代码。您可以查看此 link 以获取更多信息。
get(langObtained): Observable<String> {
let lang= langObtained;
return of(lang);
}
ngOninit(){
this.get('hi').subscribe(response=>{
//use the response
});
}
下面是一些如何使用 observables 设置语言的示例
setLang(lang: string): Observable<void> {
return fromPromise(this.storage.get('lang')).pipe(flatMap((lang) => {
const langPath = `assets/i18n/${lang || 'en'}.json`;
return this.http.get<{}>(langPath)
}), map(data => {
return ...doSomeDataMapping
}), tap((result) => {
this.data = result;
this.selectedLanguage = lang
}))
}
tap
部分仅在您确实需要有状态服务时才需要。
如果您需要对所选语言字段进行异步 getter,您的点击将如下所示:
tap((result) => {
this.data$.next(result);
this.selectedLanguage$.next(lang)
})
你需要:
private data$ = new BehaviorSubject(initialValue);
private selectedLanguage$ = new BehaviorSubject(initialValue);
在顶部。
那么 getter 将是
getSelectedLanguage$(): Observable<string> {
return this.selectedLanguage$;
}
在组件中调用
this.selectedLanguage$ = this.translateService.getSelectedLanguage$();
并与视图中的 async
管道一起使用
您可以创建一个新的 Observable
观察者接收您的 Promise
的值。
const { Observable } = rxjs;
const promise$ = new Promise(resolve => resolve('Success!'))
const observable$ = new Observable(observer => promise$.then(value => observer.next(value)))
observable$.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
一步一步:
创建Promise
,值Success!
直接为resolved
。还创建了一个 Observable
并且 observer-function
的主体侦听 Promise
.
虽然 Promise
在创建 Observable 之前设置和解析,但为什么我们得到 value
?
Promises
没有同步处理。他们是microtasks
。这些在 makrotasks
之后处理。 RxJS 默认使用 Scheduler 来处理通过其 pipes/operators/functions 的每个值。默认调度程序(您可以在 link 的底部阅读它)是一个 asyncScheduler
,它是某种内部某种 setTimeout
机制,因此是一个 makrotask
.
总和:
Observable
接收 Promise
的值,因为它是在 Promise
值之前处理的。
这是一个复杂的话题。 mikro-
和 markotask
与 JavaScript Event Queue
相关。这个 youtube video 向我解释得很好。