2017-12-27 38 views
0

このブロックの簡単な説明:アップロードするすべてのファイルであるfilesオブジェクトを持っています。その後、以前のS3関数の署名付きURLをすべて持つsignedUrlsオブジェクトがあります。オブジェクトには一致するインデックスがあります。fileIdが適切にループしていません

最初のaxios.putはファイルをアップロードし、2番目のaxios.postはファイルキーを自分のDBに保存します。 (私は正常にアップロードされていない限りDBに保存したくないため、axios.postのコールバック内の場所)

ファイルは正常にアップロードされていますが、fileIdは正しくループしていません同じfileIdを何度も繰り返し保存します。つまり、5つのファイルをアップロードすると、S3にアップロードされますが、すべてが同じDB内に同じIDを持ちます。これがなぜ起こっているのか?

fileIds = {"1": "someFileId", "2": "someOtherId" }  

for (let i = 0; i < files.length; i++) { 
    axios.put(signedUrls[i], files[i], config).then(res => { 
    axios.post('https://myapi.com/add-file', { 
     fileId: fileIds[i] 
    }).then(res => { 
     // success 
    }); 
+0

てみてください。このよう
。あるいは、少なくとも割り当てられた場所を教えてください。 – destoryer

+0

@destoryer私の編集を参照してください - ファイルIDが番号の付いたキーを持つオブジェクトである場合、このように動作します。私は元の投稿を過度に単純化しました。 – Alan

+1

すべてが私には大丈夫です。 – destoryer

答えて

1

これは、同期forループ内で非同期呼び出しを行っているためです。

post要求が呼び出されるまでに、ループは既に終了しています。

あなたはこの解決するためにPromise.allを使用することができます:あなたが正しいインデックスを使用できるように、何をやっているだろうことはあなたの約束は同期呼び出します(しかし、実際にはまだそれらを呼び出していない)を作成され、基本的に

const promises = files.map((file, i) => { 

    // create a new promise with correct index, but don't call it yet 
    return new Promise((resolve, reject) => { 
    return axios.put(signedUrls[i], file, config) 
    .then(res => { 
     return axios.post('https://myapi.com/add-file', { 
     fileId: fileIds[i] 
     }).then(res => { 
     resolve(res) 
     // todo: also handle errors here 
     }) 
    }) 
    }) 

}) 

// actually invoke your calls here 
Promise.all(promises).then(res => /* success */) 

を、約束の配列を実際に呼び出すにはPromise.allを使用します。

+0

Downvoting - それぞれの約束がそれ自身のために行動し、後で何もしない場合、なぜ 'Promise.all'を使うのですか? – destoryer

-1

iは、.postセクションの同じ値にバインドされています。
これを修正するには、自己実行匿名関数を使用できます。代わり `fileId`のループと使用内側` CONST ID = fileId`を添加

for (let i = 0; i < files.length; i++) { 
    (function(i) { 
    axios.put(signedUrls[i], files[i], config).then(res => { 
     axios.post('https://myapi.com/add-file', { 
     fileId: fileIds[i] 
     }).then(res => { 
     // success 
     }); 
    })(i); 
} 
+0

JavaScriptで参照番号で送信することはできません。 – destoryer

+0

@destoryer https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – Bsalex

+0

質問に対する回答を実際に読んでいれば、実際に変数を各反復にスコープします。 – destoryer

関連する問題