微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 for 循环同步角度执行

如何解决使用 for 循环同步角度执行

我正在使用后端作为 Spring Boot 的 Angular 9 项目。该项目基本上是CMS类型的。 在这用户可以使用反应形式生成表单一个表单可能包含多个文件选择器。我已经实现了在本地路径选择文件上传文件代码

代码工作正常,但我遇到了同步数据库中实例保存的问题。

我的流程应该是:

  1. 循环上传文件
  2. 使用上传的数据更新对象表单。
  3. 然后应将带有剩余选项和更新上传数据的对象表单保存到数据库中。

但是我的流程没有以正确的方式进行,它正在上传并且没有等待返回结果就去保存数据库,因此没有保存更新的详细信息。

以下是代码流程:

来自按钮保存的点击事件以保存表单数据:

saveClick() {
    for (const element of this.objMetaData) {
      if (element.fieldType === 'file-upload') {
        this.uploadAttachment(element.fieldName);
      }
    }
    this.savetoDatabase();
  }

这应该与更新的详细信息一起保存在最后:

savetoDatabase() {
    let relations = [];
    const instanceBody = {
      objectTypeId: this.objectTypeId,objectInstance: {...this.objectFormGroup.value,relations: relations}
    }
    this.saveInstance(instanceBody);
  }

上传文件并更新对象以保存数据:

uploadAttachment(fieldName: string) {
    let formData = new FormData();
    let fileObj: any = this.fileMap.get(fieldName);
    let fileName = fileObj.name;
    if (fileObj !== undefined) {
      formData.append('file',fileObj);
      this.attachmentService.uploadAttachment(formData).subscribe((result) => {
        if (result != null) {
          let attachmentDir = result;
          let attachmentFileName = fileName;
          let attachment = attachmentDir + '**' + attachmentFileName;
          this.objectFormGroup.value[fieldName] = attachment;             
        } else {              
          console.log("File not uploaded.")
        }
      });
    }
  }

代码流不顺。

this.savetoDatabase();

这是在 for 循环中上载之前调用的。我尝试了很多事情,比如将 forEach 更新为 for 循环、异步、等待等,但都没有正常工作。

如何解决问题使执行同步。

解决方法

要解决这个问题,这里的方法是使用Rxjs。从 uploadAttachment 函数中获取所有 Observable 并将它们与 combinelatest 组合。然后订阅这个组合钩子以在所有调用都返回后运行 saveToDatabase

在代码中它会呈现类似

saveClick() {
    let observables: Observable<any>[] = [];
    for (const element of this.objMetaData) {
          if (element.fieldType === 'file-upload') {
            let uploadObservable = this.uploadAttachment(element.fieldName);
            if(uploadObservable) observables.push(uploadObservable);
          }
    }
    combineLatest(observables)
    .pipe(take(1))
    .toPromise()
    .then(()=>{ 
        this.saveToDatabase();
    });
}

为此,我们还需要 uploadAttachment 函数来返回上传的 observable。

uploadAttachment(fieldName: string): Observable<any> {
    // ... 
    return this.attachmentService.uploadAttachment(formData)
    .pipe(tap(result=>{ 
        // ... Callback code goes here 
    }));
}

请注意,我正在使用 Rxjs 运算符管道、取和点。

如果你还不知道,我相信你真的应该看看here。在 angular 的网站上还有一个关于 rxjs 的 article

编辑:添加了stackblitz demo

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。