如何在不使代码挂起的情况下删除以下承诺捕获?

时间:2017-06-15 07:43:11

标签: javascript promise

以下代码循环遍历某些表单字段。如果该字段是必须上载的文件,则会运行api.uploadPhoto功能(在上传照片后设置有效负载)。如果直接设置有效负载时该字段是正常输入:

formFields.forEach(field => {
  if (hasUploadFiles(field)) {
    uploadPhotoPromise = new Promise((resolve, reject) => {
      uploads.queued.push(file)
      api.uploadPhoto(file, field).then(uploadedPhoto => {
        uploads.finished.push(field)
        if (uploads.queued.length === uploads.finished.length) {
          payload[field.name] = uploadedPhoto
          resolve()
        } else {
          reject()
        }
      }).catch(error => {
        console.log('error:', error)
        reject()
      })
    }).catch(error => {
      console.log('error:', error)
    })
  } else {
    payload[field.name] = field.value
  }
})

Promise.all([uploadPhotoPromise]).then(values => {
  // update action
}

代码有效。但是,所有catch使它看起来有些混乱。

我尝试删除它们,但如果删除其中的任何一个代码就会挂起(Promise.all中的代码永远不会运行)。为什么是这样?如何重构这些代码而不使用所有那些catch语句而不使其挂起?

原始代码(加上Bergi建议的修改):

const buildingFormPromise = utils.mapDeep(this.buildingForm.schema, field => {
  if (!field.name) return // fields not in the database
  else if (utils.hasUploadFiles(field)) {
    utils.eachCall(field.value, (file, index) => {
      field.userId = this.user.id
      this.uploads.queued.push(file)
      this.$set(this.uploads.queued, index, { progress: 30 })
      return api.uploadPhoto(file, field).then(uploadedPhoto => {
        this.$set(this.uploads.queued, index, { progress: 100 })
        return loadImage(uploadedPhoto, () => {
          this.uploads.finished.push(field)
          if (this.uploads.queued.length === this.uploads.finished.length) {
            console.log('This runs after the code inside Promise.all')
            buildingPayload[field.name] = uploadedPhoto
          }
        })
      })
    })
  } else {
    return Promise.resolve(buildingPayload[field.name] = field.value)
  }
})

Promise.all([buildingFormPromise]).then(values => {
  console.log('This runs before the files are uploaded')
})

1 个答案:

答案 0 :(得分:1)

你需要将所有承诺的数组传递给Promise.all,你应该避免使用Promise constructor antipattern。如果您不想处理单个上传失败,可以将.catch移至最后。

var fieldValuePromises = formFields.map(field => {
  if (hasUploadFiles(field)) {
    return api.uploadPhoto(file, field).then(uploadedPhoto => {
      return payload[field.name] = uploadedPhoto;
    });
  } else {
    return Promise.resolve(payload[field.name] = field.value);
  }
});

Promise.all(fieldValuePromises).then(values => {
  // update action
}).catch(error => {
  // at least one upload failed
  console.log('error:', error)
});
相关问题