【问题标题】:Chain promises then return observable链承诺然后返回可观察的
【发布时间】:2019-07-23 00:48:49
【问题描述】:

这很令人困惑。我正在使用 angular(ionic) 并调用两个链承诺,然后希望返回如下可观察到的。我尝试在两个 Promise 前添加 return,但当然会引发编译错误。

Type 'Promise<Observable<{ formInstanceId: any; questionId: any; repeatId: any; filename: any; isEquipment: any; }>>' is not assignable to type 'Observable<any>'.   Property '_isScalar' is missing in type 'Promise<Observable<{ formInstanceId: any; questionId: any; repeatId: any; filename: any; isEquipment: any; }>>'

我曾想过使用 from(promise1) 和 from(promise2) 但后来变得更加混乱..

我想将其更改为完全可观察的主要原因是因为我想在下面代码末尾的 post() 中使用 timeout()

public uploadFile(formInstanceId, questionId, repeatId, filePath, isEquipment): Observable<any> {

    this._file.resolveLocalFilesystemUrl(filePath).then(result => {
    console.log("fileSelected", result);

    let fileName = result.name;
    let nativeURL = result.nativeURL;
    let path = nativeURL.substring(0, nativeURL.lastIndexOf("/"));

    this._file.readAsArrayBuffer(path, fileName).then(buffer => {
      let imgBlob = new Blob([buffer], {type: "image/jpeg"});

      let params = {fileName: 'attachment'};
      let query = this.encodeQueryData(params);

      let uploadFileURL = this._networkService.serverUrl + '/api/upload?' + query;


      return this._networkService.postFile(uploadFileURL, fileName, imgBlob).pipe(map(response => {
          console.log(response);
          return {
            formInstanceId: formInstanceId,
            questionId: questionId,
            repeatId: repeatId,
            filename: response[0].filepath,
            isEquipment: isEquipment
          };
        },
        error => {
          return throwError(error);
        }
      ));


    });
  })

}

【问题讨论】:

  • 你到底遇到了什么错误?
  • @SmokeyDawson 更新问题
  • 您是否有理由要返回 Observable 而不是 Promise?
  • @SmokeyDawson 在 network.postFile 中使用超时。而不是使用 .subscribe(),pipe(map) 甚至没有到达..

标签: angular promise observable


【解决方案1】:

您可以使用 RxJs 中的 from 运算符,它将任何 Promise 转换为 Observable 并将其进一步链接(可能使用 flatMap)。 参考:https://www.learnrxjs.io/operators/creation/from.html

这里回答了类似的问题:

Return Observable inside the Promise

How to return Observable after some Promise get resolved in Ionic 2/Angular 2? (这里提到的fromPromise操作符应该换成新的from操作符)

另一种选择是在 Typesript/ES6 中使用 async await 关键字。无论您在哪里调用 uploadFile 方法,只需使用 (await uploadFile(formInstanceId, questionId, repeatId, filePath, isEquipment)) 即可返回由 networkService.postFile() 方法返回的 observable。

你的方法会变成:

 public async uploadFile(formInstanceId, questionId, repeatId, filePath, isEquipment): Promise<Observable<any>> {

    const result = await this._file.resolveLocalFilesystemUrl(filePath);
    console.log("fileSelected", result);

    let fileName = result.name;
    let nativeURL = result.nativeURL;
    let path = nativeURL.substring(0, nativeURL.lastIndexOf("/"));

    const buffer = await this._file.readAsArrayBuffer(path, fileName);
    let imgBlob = new Blob([buffer], {type: "image/jpeg"});

    let params = {fileName: 'attachment'};
    let query = this.encodeQueryData(params);

    let uploadFileURL = this._networkService.serverUrl + '/api/upload?' + query;

    return this._networkService.postFile(uploadFileURL, fileName, imgBlob).pipe(map(response => {
        console.log(response);
        return {
        formInstanceId: formInstanceId,
        questionId: questionId,
        repeatId: repeatId,
        filename: response[0].filepath,
        isEquipment: isEquipment
        };
    },
    error => {
        return throwError(error);
    }
    ));
}

这是你的消费方式:

(await uploadFile(formInstanceId, questionId, repeatId, filePath, isEquipment)).subscribe(result=> { /* ...Your code here... */ });

异步等待参考:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-7.html

【讨论】:

  • 谢谢,在方法签名中,返回类型定义为promise。对吗?
  • Yes Promise of Observable of any。即Promise&lt;Observable&lt;any&gt;&gt;
猜你喜欢
  • 2019-11-12
  • 2020-01-08
  • 2023-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
相关资源
最近更新 更多