次のコードは、いくつかのフォームフィールドをループします。フィールドをアップロードする必要があるファイルの場合は、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')
})
「ハングさせない」とはどういう意味ですか? – Bergi
2つのこと:1)Promiseの配列を作成しない。各反復ごとに1つの 'uploadPhotoPromise'が繰り返しています。 2)最初の 'catch()'では 'resolve()'を呼び出すことはできません。なぜなら、あなたはこの関数にアクセスすることができず、あなたは約束外にいるからです。このコードは、おそらく 'catch 'の内部に入っていないため動作します。そうでなければ、Promisesをどのように使うのかは分かりません。 – vassiliskrikonis
このコードは、不要な 'catch'esよりも間違っています。 'uploadPhotoPromise'で' Promise.all'が動作するとは思っていません。キューイングのロジックは非常に怪しいです(キューではありませんが、並列でも動作しません)。そして、 'Promise'コンストラクタアンチパターン](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)。コードが実際に 'formFields'で何をしたいのですか? – Bergi