Promise 必须是异步的 - Angular 9

Promise must be async - Angular 9

我想单独上传一系列文件,然后 post 只有在文件完成后才上传其他数据。到目前为止,每个文件都有自己的请求上传,但我无法让其他请求等待文件完成上传 - 它们都同时执行,尽管 async/await.

这是我的代码的简化版本(其中 run() 需要是可观察的或承诺的,postOtherDatas() 需要等待 uploadFileList() 完成):

public async run(data: Data): Promise<Object> {
    await this.uploadFileList(data.files); // run this first
    return this.postOtherDatas(data.otherData).subscribe(); // run this only if uploadFileList() is done
}
    
public async uploadFileList(files: File[]) {
  return await Promise.all(files.map((file) => {
    this.uploadFile(file).subscribe();
  }));
}

public uploadFile(file: File): Observable<HttpEvent<any>> {
  const req = new HttpRequest('POST', `apiUrl/postfile`, 
    formData, { withCredentials: true });
  return this.http.request(req);
}
  
public postOtherDatas(formData: FormData) {
  return this.http.post('apiUrl/postotherdata',
    formData, { withCredentials: true }
  );
}

我也试过了,但是 postOtherDatas() 从来没有被调用过:

public run(data: Data): Observable<Object> {
   return this.uploadFileList(data.files).then(() => this.postOtherDatas(data.otherData).subscribe())
}

rxjs 订阅不是承诺:

public async uploadFileList(files: File[]) {
  return await Promise.all(files.map((file) => {
    // Not a promise!
    this.uploadFile(file).subscribe();
  }));
}

如果你想继续使用 promise,你可以这样做:

public async uploadFileList(files: File[]) {
  return await Promise.all(files.map((file) => {
    return this.uploadFile(file).toPromise();
  }));
}

同样需要在您的 run 方法中完成:

public async run(data: Data): Promise<Object> {
    await this.uploadFileList(data.files); // run this first
    return this.postOtherDatas(data.otherData).toPromise(); // run this only if uploadFileList() is done
}

但是:我建议你更慎重地使用 rxjs,它有一些很好的工具来处理更复杂的异步性。例如。 Promise.all可以使用forkJoin函数实现。