【问题标题】:Observable.subscribe not always execute http requestObservable.subscribe 并不总是执行 http 请求
【发布时间】:2021-10-09 23:21:42
【问题描述】:

我正在尝试编写 Angular 应用程序将切片文件发送到后端。

我正在对文件做什么:

  1. 将多个文件剪切成数组(每个切片有 1MB)
 const array = [];
            for (let i = 0; i < this.File.file.size; i += 1048576) {
              array.push(this.File.file.slice(i, i + 1048576));
            }
  1. 对于每个文件调用函数 UploadAllSlices()
private UploadAllSlices() {
    let sliceNumber = 0;
    const fileUploadSub: Subject<void> = new Subject();

    const chunkObserver = new Observable(observer => {
      const chunkUploadSub: Subscription = fileUploadSub.subscribe(
        _ => {        
          this.uploadFile(sliceNumber).subscribe((chunkReponse: any) => {
                // my logic here
           },
        e => {
          console.log('ERROR', e);
        }
      );
        sliceNumber++;
      fileUploadSub.next();
    });
    }).pipe(
      takeUntil(this.pause$),
      retry(1000)
    );
  }
  1. 函数uploadFile(在UploadAllSlices()内部使用)
private uploadFile (index: number) {
    const formData = new FormData();

    formData.append(); // other data not important 
    formData.append(); // other data not important 
    formData.append('SliceContent', this.File.array[index]);
   
    return this.http.patch(URL , formData).pipe(
      retry(1000),
      takeUntil(this.pause$)
    );
  }

当我上传 1-3 个文件时,一切正常。但是当我尝试一次上传 10-15 个文件时,一些文件会随机卡住。 (有时所有文件都上传,有时1-2个文件卡住,有时5个文件非常随机地卡住)

对于那些卡住的文件 this.http.patch 没有被执行,所以我无法得到响应并在这里制定我的逻辑:

  this.uploadFile(sliceNumber).subscribe((chunkReponse: any) => {
                // logic here
           }

知道为什么它会随机卡住,为什么订阅不发送http.patch 到后端?

【问题讨论】:

  • 你肯定从UploadAllSlices 中遗漏了一些东西,因为这个函数永远不会像写的那样做任何事情,因为它在语法上是无效的。我猜它是一个复制/粘贴错误,因为它适用于 1-3 个文件。但是对于 15 个文件,您需要实现某种批处理方案,而这只是散布着 rxjs 反模式,这会导致 1 使这变得困难,而 2 会使调试变得更加困难

标签: angular typescript rxjs frontend


【解决方案1】:

你没有处理错误。

return this.http.patch(URL , formData).pipe(
  retry(1000),
  takeUntil(this.pause$),
  catchError(() => of(null))
);

this.uploadFile(sliceNumber).subscribe(
  (chunkReponse: any) => { /* logic here */ },
  (err) => console.log('oops', err);
);

如果一个 Observable 流发生错误而没有处理错误,它将翻倒并且永远不会再次发出(尽管 HTTP Observables 只发出一次然后完成 - 除非它们出错)。请注意,of(null) 中的 null 将被传递到成功块,这就是为什么您只需要这两种方法之一。在您的情况下,第二个可能更合适,因为它将提供有关 HTTP 错误的更多信息。

您的浏览器调试控制台网络选项卡还应提供有关 HTTP 错误的更多信息。

我在想,连续上传 15 个 1MB 的 HTTP 请求有哪些浏览器限制。也许浏览器限制导致失败。还要检查您的服务器是否正在接收这些请求,如果是,它会给出什么响应。

【讨论】:

  • 我添加了处理错误( (err) => console.log('oops', err); )但没有日志:/。我的服务器没有收到新请求。看起来前端随机停止发送新请求而没有任何错误
  • 您在网络选项卡中看到 HTTP 请求了吗?他们正在制造吗?他们的反应如何?
  • 它们不是在网络标签中创建的。它只是卡住而没有发送下一个请求。也许它的Firefox故障?有什么方法可以检查吗?
  • "每个切片都有 1MB" - 你尝试过更小的切片吗?抱歉,如果它不在网络标签中,不知道如何检查它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
相关资源
最近更新 更多