2017-12-27 43 views
0

이 블록에 대한 간략한 설명 : 내가 업로드 할 모든 파일 인 files 개체가 있습니다. 그런 다음 이전 S3 기능의 모든 서명 된 URL을 가진 signedUrls 개체가 있습니다. 개체의 색인이 일치합니다.fileId가 제대로 루핑되지 않습니다.

첫 번째 axios.put은 파일을 업로드하고 두 번째 axios.post은 파일 키를 내 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

를 추가해보십시오'const를 ID = fileId' 대신 fileId''의. 적어도 할당 된 위치를 알려주십시오. – 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 섹션의 동일한 값에 바인딩되어 있습니다.
이 문제를 해결하려면 자체 실행 익명 기능을 사용할 수 있습니다. 이처럼
: 루프와 내부에서

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

질문에 대한 답변을 실제로 읽은 경우, let '변수를 실제로 반복 할 때마다 범위를 지정합니다. – destoryer