Angular 2:将 Observable 转换为 Promise

问题描述 投票:0回答:9

问)如何将以下可观察量转换为承诺,以便我可以使用

.then(...)
调用它?

我的方法我想转换为承诺:

  this._APIService.getAssetTypes().subscribe(
    assettypes => {
        this._LocalStorageService.setAssetTypes(assettypes);
    },
    err => {
        this._LogService.error(JSON.stringify(err))
    },
    () => {}
  ); 

它调用的服务方法:

  getAssetTypes() {
    var method = "assettype";
    var url = this.apiBaseUrl + method;

    return this._http.get(url, {})
      .map(res => <AssetType[]>res.json())
      .map((assettypes) => {
        assettypes.forEach((assettypes) => {
          // do anything here you might need....
      });
      return assettypes;
    });      
  }  

谢谢!

typescript angular promise observable
9个回答
142
投票

rxjs7

lastValueFrom(of('foo'));

https://indepth.dev/posts/1287/rxjs-heads-up-topromise-is-being-deprecated

rxjs6

https://github.com/ReactiveX/rxjs/issues/2868#issuecomment-360633707

不要管道。默认情况下它位于 Observable 对象上。

Observable.of('foo').toPromise(); // this

rxjs5

import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';

...

this._APIService.getAssetTypes()
.map(assettypes => {
  this._LocalStorageService.setAssetTypes(assettypes);
})
.toPromise()
.catch(err => {
  this._LogService.error(JSON.stringify(err));
});

23
投票

observable 可以像这样转换为 Promise:

import { firstValueFrom, lastValueFrom } from 'rxjs';
...
lastValueFrom(observable).then(lastValue=>...);
firstValueFrom(observable).then(firstValue=>...);

toPromise()
是之前的解决方案,从 RxJS 7 开始已弃用,它是:

let promise=observable.toPromise();


 

13
投票

你并不真的需要这样做,只需......

import 'rxjs/add/operator/first';


this.esQueryService.getDocuments$.first().subscribe(() => {
        event.enableButtonsCallback();
      },
      (err: any) => console.error(err)
    );
    this.getDocuments(query, false);

first() 确保订阅块仅被调用一次(之后就好像你从未订阅过一样),与 Promise then() 完全相同


13
投票

在您的情况下,使 Observable 成为 Promise 的正确方法如下

getAssetTypesPromise() Observable<any> {
  return new Promise((resolve, reject) => {
      this.getAssetTypes().subscribe((response: any) => {
        resolve(response);
      }, reject);
    });
}


11
投票

编辑:

.toPromise()
现已在 RxJS 7 中弃用(来源:https://rxjs.dev/deprecations/to-promise

新答案:

作为已弃用的 toPromise() 方法的替代,您应该使用 两个内置静态转换函数之一firstValueFrom 或 最后值来自。

示例:

import { interval, lastValueFrom } from 'rxjs';
import { take } from 'rxjs/operators';
 
async function execute() {
  const source$ = interval(2000).pipe(take(10));
  const finalNumber = await lastValueFrom(source$);
  console.log(`The final number is ${finalNumber}`);
}
 
execute();
 
// Expected output:
// "The final number is 9"

旧答案:

很多评论都声称

toPromise
已弃用,但正如您在 here 看到的那样,事实并非如此。

所以请直接使用

toPromise
(RxJs 6),如下所示:

//return basic observable
const sample = val => Rx.Observable.of(val).delay(5000);
//convert basic observable to promise
const example = sample('First Example')
  .toPromise()
  //output: 'First Example'
  .then(result => {
    console.log('From Promise:', result);
  });

异步/等待示例:

//return basic observable
const sample = val => Rx.Observable.of(val).delay(5000);
//convert basic observable to promise
const example = await sample('First Example').toPromise()
// output: 'First Example'
console.log('From Promise:', result);

阅读更多这里


注意:否则您可以使用

.pipe(take(1)).toPromise
但正如所说,使用上面的示例应该不会有任何问题。


5
投票

toPromise 在 RxJS 7 中已弃用

用途:

  1. lastValueFrom

当我们对值流感兴趣时使用。和前者一样工作

toPromise

示例

public async getAssetTypes() {
  const assetTypes$ = this._APIService.getAssetTypes()
  this.assetTypes = await lastValueFrom(assetTypes$);
}
  1. firstValueFrom

当我们对值流不感兴趣而只对第一个值感兴趣,然后取消订阅流时使用

public async getAssetTypes() {
  const assetTypes$ = this._APIService.getAssetTypes()
  this.assetTypes = await firstValueFrom(assetTypes$); // get first value and unsubscribe
}

0
投票

只需一行代码即可将 Observable 转换为 Promise:

let promisevar = observable.toPromise()

现在您可以在promisevar上使用then来根据您的要求应用then条件。

promisevar.then('Your condition/Logic');

0
投票

我喜欢它原始的,所以这个自从 toPromise() 不再存在了

   const status = await new Promise<boolean>((resolve, reject) => {
     someObs$.subscribe({
      next: resolve,
      error: reject,
    });
  });

一种复杂的方法是使用 https://rxjs.dev/api/index/function/lastValueFrom

  const replyTo = new AsyncSubject();

  replyTo.next(false);
  replyTo.next(false);
  replyTo.next(true);

  replyTo.complete();

  const status = await lastValueFrom(replyTo) // true

0
投票

对于最顽固的人,我发现这个解决方法可以永远保留 toPromise() 。将其放入您的 main.ts 或类似文件中(用于引导整个应用程序的文件):

declare module "rxjs" {
    interface Observable<T> {
        /**
         * Extension method. Applies 'lastValueFrom' to Observable<T>.
         */
        toPromise(): Promise<T | undefined>;
    }
}

Observable.prototype.toPromise = function <T>(this: Observable<T>): Promise<T> {
    return lastValueFrom(this);
};

第一部分声明了 toPromise 的新类型,第二部分实际实现了它。当 toPromise 尚未被删除时,这已经可以工作了,并将继续工作。

© www.soinside.com 2019 - 2024. All rights reserved.