簡體   English   中英

如何使用Angular 4在可觀察對象內部進行http promise調用?

[英]Using Angular 4 how do I make a http promise call inside of an observable?

如何使用Angular 4在Observable內部進行http promise調用? 我正在使用具有Cognito聯合帳戶的AWS API Gateway。 我們必須使用apigClient.invokeApi對每個http調用進行簽名。 我想獲取promise調用的結果,並以可觀察的方式返回結果。 下面的代碼可以觸發,但根本無法到達其余的可觀察代碼。 當我訂閱可觀察對象時,它永遠不會到達訂閱內部的代碼。 我也沒有任何編譯錯誤。 任何幫助都會有所幫助。

public upload(image, fileType): Observable<FileReturnData> {
  const apigClient = apigClientFactory.newClient({
    accessKey: this.auth.cognitoAccessKey,
    secretKey: this.auth.cognitoSecretKey,
    sessionToken: this.auth.cognitoSessionToken,
    invokeUrl: this.auth.URL
  });
  const data = new FileData()
  data.image = image;
  data.fileType = fileType;
  const uploadPromise = apigClient.invokeApi({}, '/users/upload', 'POST', {}, {image: image, fileType: fileType});


const observable = new Observable<FileReturnData>(observer => {

    uploadPromise.then(function (uploadResult) {
      console.log(uploadResult); // I see this in the console

      const fileReturnData = new FileReturnData();

      const responseBody = JSON.parse(uploadResult.body);

      fileReturnData.filename = responseBody.filename;
      console.log('IN OBSERVABLE');  //  I never get to this result
      observer.next(fileReturnData);
      observer.complete();


      return () => console.log('upload image user observable disposed');

    }).catch(function (uploadImageError) {

      return () => console.error(uploadImageError);
    });

  });

  return observable;

}

我只對這樣的Ajax調用使用嵌套的promise,但是我相信您的代碼問題,使用可觀察的對象和嵌套的promise是您過早啟動invokeApi http調用,對/users/upload的調用未按預期完成,因此通過upload返回的observable的訂戶正在等待observer.complete(),這會產生意想不到的后果,因為您正在uploadPromise.then中調用observer.complete()uploadPromise.then可能已經完成或尚未完成。

看看這是否可以解決您的代碼:

  public upload(image, fileType): Observable<FileReturnData> {
      const apigClient = apigClientFactory.newClient({
        accessKey: this.auth.cognitoAccessKey,
        secretKey: this.auth.cognitoSecretKey,
        sessionToken: this.auth.cognitoSessionToken,
        invokeUrl: this.auth.URL
      });

    const observable = new Observable<FileReturnData>(observer => {

        const data = new FileData()
        data.image = image;
        data.fileType = fileType;

        apigClient.invokeApi({}, '/users/upload', 'POST', {}, {image: image, fileType: fileType})
        .then(function (uploadResult) {
          console.log(uploadResult); // I see this in the console

          const fileReturnData = new FileReturnData();

          const responseBody = JSON.parse(uploadResult.body);

          fileReturnData.filename = responseBody.filename;
          console.log('IN OBSERVABLE');  //  I never get to this result
          observer.next(fileReturnData);
          observer.complete();

        }).catch(function (uploadImageError) {

          //handle error
        });

      });

      return observable;

    }

如果我完全了解您的情況,我個人發現對HTTP調用使用嵌套的Promise比較容易管理。 這是您可以使用的代碼版本,僅使用Promise,然后任何Observable都可以調用upload並等待其完成:

  public upload(image, fileType): Promise<FileReturnData> {
      const apigClient = apigClientFactory.newClient({
        accessKey: this.auth.cognitoAccessKey,
        secretKey: this.auth.cognitoSecretKey,
        sessionToken: this.auth.cognitoSessionToken,
        invokeUrl: this.auth.URL
      });



    const promise = new Promise<FileReturnData>((resolve, reject) => {

        const data = new FileData()
        data.image = image;
        data.fileType = fileType;
        //I moved this "invokeApi" call here because it does not seem like a factory method
        //it seems like you start an ajax call when "invokeApi" is called
        //so you must keep this all within the promise you are returning to callers
        //of the upload function
        apigClient.invokeApi({}, '/users/upload', 'POST', {}, {image: image, fileType: fileType})
        .then(uploadResult => {
          console.log(uploadResult); // I see this in the console

          const fileReturnData = new FileReturnData();

          const responseBody = JSON.parse(uploadResult.body);

          fileReturnData.filename = responseBody.filename;

          resolve(fileReturnData);

        }, msg => {
            reject(msg);
        }).catch(ex => {
          return () => console.error(ex);
        });

      });

      return promise;

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM