Angular 2:将Observable转换为Promise

Dav*_*ave 46 promise observable typescript angular

问)如何将以下observable转换为promise,以便我可以调用它.then(...)

我希望转换为承诺的方法:

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

它调用的服务方法:

  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;
    });      
  }  
Run Code Online (Sandbox Code Playgroud)

谢谢!

Gün*_*uer 78

rxjs6

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

不管.它默认位于Observable对象上.

Observable.of('foo').toPromise(); // this
Run Code Online (Sandbox Code Playgroud)

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));
});
Run Code Online (Sandbox Code Playgroud)

  • @GünterZöchbauer有`import'rxjs/operator/add/toPromise';`已被改为:`import'rxjs/add/operator/toPromise';`? (2认同)
  • toPromise已弃用.我们现在怎么做? (2认同)

Luc*_* C. 16

observable可以转换成这样的承诺:

let promise=observable.toPromise();
Run Code Online (Sandbox Code Playgroud)


dan*_*y74 12

你真的不需要这样做......

import 'rxjs/add/operator/first';


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

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


Teo*_*irs 5

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

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

  • 这可以进一步简化为`return new Promise((resolve, reject) =&gt; this.getAssetTypes().subscribe(resolve, reject));` (2认同)

Cur*_*rse 5

很多评论都声称toPromise已弃用,但正如您在此处看到的那样事实并非如此。

所以请使用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);
  });
Run Code Online (Sandbox Code Playgroud)

异步/等待示例:

//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);
Run Code Online (Sandbox Code Playgroud)

在这里阅读更多。

并请删除这个错误的声明说toPromise已弃用。


注意:否则您可以使用.pipe(take(1)).toPromise但如上所述,使用上面的示例应该没有任何问题。


Alf*_*Moh 5

toPromise在 RxJS 7 中已弃用。

使用:

  1. lastValueFrom

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

例子

public async getAssetTypes() {
  const assetTypes$ = this._APIService.getAssetTypes()
  this.assetTypes = await lastValueFrom(assetTypes$);
}
Run Code Online (Sandbox Code Playgroud)
  1. firstValueFrom

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

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