【问题标题】:Upload file chunks sequentially using forkjoin and wait for response before firing next api call使用 forkjoin 顺序上传文件块并在触发下一个 api 调用之前等待响应
【发布时间】:2021-01-28 22:54:40
【问题描述】:

我有以下一段代码,基本上我正在尝试将大文件的块上传到从服务返回的签名 url..

只有在返回的 forkjoin 中的所有 PUT 请求都已完成后,我才需要调用 uploadcompleted 端点,但我面临的问题是我无法等待将块上传到签名的 url。

我在这里做错了什么?任何帮助将不胜感激。提前致谢。

filechunks(chunk: any, uploadUrls: string[], index) {
    let observableBatch = [];

    const headers: HttpHeaders = new HttpHeaders({
      'content-type': 'application/json'
    });
    observableBatch.push(this._http.put<any>(uploadUrls[index], chunk, { headers }))
    return forkJoin(observableBatch).pipe(delay(1000));
    // const createRequest = () => of(this._http.put<any>(uploadUrls[index], chunk, { headers }));
    // return forkJoin(createRequest).pipe(delay(1000));
  }

uploadfileinchunks(uniqueFileId: string, uploadId: string, chunks, uploadUrls): Observable<any> {
    let response = [];

    chunks.map( (chunk, i) => {
      let response = this.filechunks(chunk, uploadUrls, i).toPromise();
      console.log(response) 
    });


    const params = {
      some-id: some-id
    };

    return this._http.post<FileData>(
      `${somurl}/uploadcompleted`,
      {},
      {  {}, params }
    );
  }

【问题讨论】:

  • this.filechunks(chunk, uploadUrls, i).toPromise();这将异步执行,uploadfilechunks 将立即运行 post 而无需等待

标签: javascript angular promise rxjs observable


【解决方案1】:

解读:

您的代码没有真正的意义,因此很难弄清楚您甚至想做什么

filechunks(chunk: any, uploadUrls: string[], index) {
  const headers: HttpHeaders = new HttpHeaders({
    'content-type': 'application/json'
  });

  // observableBatch is an array of size 1. Why bother?
  const observableBatch = [];  
  observableBatch.push(
    this._http.put<any>(
      uploadUrls[index], 
      chunk, 
      { headers }
    )
  );

  // You're runnung forkJoin on a single observable? Again, why?
  return forkJoin(observableBatch).pipe(delay(1000));
}

uploadfileinchunks(uniqueFileId: string, uploadId: string, chunks, uploadUrls): Observable<any> {
  
  // Here, response is declared, but it's never used. You can delete this.
  let response = [];

  // chunks#map is a mapping function, but you're mapping every element to
  // null. Maybe what you mean is forEach?
  chunks.map( (chunk, i) => {
    // This a new response, this one is a promise. If you want the result
    // returned from filechunks, you'd need to resolve this promise
    // with response.then(LAMBDA) or await response
    // Also, mixing observables and promises is often a code smell.
    let response = this.filechunks(chunk, uploadUrls, i).toPromise();
    // You're logging a promise object here, not its resolved value
    console.log(response) 
  });

  // Not sure what this is?
  const params = {
    some-id: some-id
  };

  // call the uploadcompleted endpoint, but you haven't waited 
  // for your other calls to complete. That's what this question is about.
  return this._http.post<FileData>(
    `${somurl}/uploadcompleted`,
    {},
    {  {}, params }
  );
}

我对你打算做什么的最佳猜测:

我显然无法对此进行测试,而且它还是不完整的,因为您的问题非常模糊,但也许这会引导您走上正确的道路?

请记住,uploadfileinchunks 返回一个 Observable,并且在您 subscribe 之前,observable 不会做任何事情。因此,无论在何处调用此代码,您都需要确保这样做。

filechunks(chunk: any, uploadUrls: string[], index) {
  return this._http.put<any>(
    uploadUrls[index], 
    chunk, 
    { 
      headers: new HttpHeaders({
        'content-type': 'application/json'
      })
    }
  ).pipe(
    delay(1000)
  );
}

uploadfileinchunks(uniqueFileId: string, uploadId: string, chunks, uploadUrls): Observable<any> {

  return forkJoin(chunks.map(
    (chunk, i) => this.filechunks(chunk, uploadUrls, i)
  ).pipe(
    map(response => ({
      some-id: "some-id"
    })),
    switchMap(params => this._http.post<FileData>(
      `${somurl}/uploadcompleted`,
      {},
      {  {}, params }
    ))
  );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-05
    • 2020-08-06
    • 2021-04-17
    • 2021-11-18
    • 2020-01-08
    • 1970-01-01
    • 2021-07-23
    • 2015-07-15
    相关资源
    最近更新 更多