连锁承诺然后返回可观察

时间:2019-03-01 02:04:59

标签: angular promise observable

这很令人困惑。我正在使用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);
        }
      ));


    });
  })

}

1 个答案:

答案 0 :(得分:0)

您可以从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()方法返回的可观察对象。

您的方法将变为:

 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