如何在 Angular 收到服务器响应之前阻止任何执行?

How to prevent any execution until got response from server in Angular?

我是 Angular 的新手,我的要求如下。

AService 中的一个函数,return 是真还是假

BComponent 中的一个函数,它从服务中排除了一个值。

function A()
{
    isSuccess: boolean = false;
    //logic
    if (err) 
    {
       this.isSuccess = false;
    }
    else 
    {
       this.isSuccess = true;
    }
    return this.isSuccess;
}

function B()
{
    var obj = new Service();
    var ret=obj.A(); 
}

此处函数 B 中“ret”的值始终为 false。这是因为在我们收到服务器的响应之前,函数 A 的 return 为 false。

实例

upload.service.ts

export class S3FileUploadService 
{
   isSuccess: boolean = false;
   constructor(private http: HttpClient) { }
   uploadFile(file: File, bucketName: string, fileName: string): boolean 
   {
      debugger;
      const contentType = file.type;
      const bucket = new S3(
      {
         accessKeyId: '<accessKeyId>',
         secretAccessKey: '<secretAccessKey>',
         region: '<region>'
      });
      const params = {
         Bucket: bucketName,
         Key: fileName,
         Body: file,
         ContentType: contentType};


      bucket.putObject(params, function (err: any, data: any) {          
         if (err) 
         {
            this.isSuccess = false;
         }
         else 
         {
            this.isSuccess = true;
         }

    });
    return this.isSuccess;
  }
}

upload.component.ts

var isSucess=this.uploadService.uploadFile(file, this.bucket, file.name);
if(isSucess){
   //further logic of component
}

这里在执行回调函数之前它return对组件是假的。但在 3 到 4 秒后,它进入回调函数并将其设置为 true。但为时已晚,因为组件逻辑已经执行。

我也用过 promise() 和 then()。但运气不好。

更新

已承诺

服务

在相同的函数中,我使用了如下所示的 putObject 方法

return await bucket.putObject(params).promise()

分量

this.uploadService.asynchUploadFile(file, this.bucket, file.name).then((data) => { 
      if (!data.$response.error) {
        this.IsSuccess=true
      }
      else
         this.IsSuccess=false
})

你不应该 return 与 isSuccess 是布尔值 属性,而是 PromiseRxJS#Observable。在您调用 uploadFile 的代码中,如果您 return 承诺,则可以使用 .then() 处理回调,如果您选择可观察的,则可以使用 .subscribe() 处理回调。

我不确定 S3 是什么,但当我搜索它时,您可能正在使用 Amazon 的 aws。 S3 实例有一个 promise 函数,你应该 return 那个。 https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-promises.html

您应该将组件中的 isSuccess 属性 视为 3 状态值。初始值可以是 undefined ,表示您正在等待结果,在您的 then 回调中将值分配给它之后。或者您可以引入另一个 属性,例如 isPending,在调用服务之前将其设置为 true,并在回调中将其设置回 false。

你应该在你的服务中这样做:

export class S3FileUploadService 
{
   constructor(private http: HttpClient) { }
   uploadFile(file: File, bucketName: string, fileName: string): boolean 
   {
      const contentType = file.type;
      const bucket = new S3({
         accessKeyId: '<accessKeyId>',
         secretAccessKey: '<secretAccessKey>',
         region: '<region>'
      });
      const params = {
         Bucket: bucketName,
         Key: fileName,
         Body: file,
         ContentType: contentType
      };
      return bucket.putObject(params).promise()
  }
}

之后您可以在您的组件中执行此操作:

...

this.uploadService.uploadFile(file, this.bucket, file.name).then((data) => { 
  this.IsSuccess = !data.$response.error;
  // Do all data related stuff here.
});

// No other code should be written here.

@Aijaz 这是一个工作演示,说明了一个非常相似的场景。基于 Observables:https://angular-ivy-dgzmep.stackblitz.io.

该服务提供了演示冗长 API 调用的此功能:

  getWithSuccess(): Observable<boolean> {
    return of(true).pipe(delay(3000));
  }

组件调用此服务如下:

this.success$ = this.myService.getWithSuccess();

this.success$
.pipe(tap(response => console.log(response)))
.subscribe();

同样的失败,所以你可以看到这两种情况。