如何将我的承诺更改为可观察的?

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-markotaskJavaScript Event Queue 相关。这个 youtube video 向我解释得很好。