생활
lambda excel file upload 간단 소스구현마무리 도와주세요..
람다에 함수를 zip 으로 업로드 하였습니다.
아래 zip 파일 첨부합니다.
https://drive.google.com/file/d/15Ti48t94USj8P7fIYPDVbQvx1zfOioKL/view?usp=sharing
람다에서 실행후 로그 입니다.
소스 보시면 s3.putObject 후에 callback 부분에도 로그가 있는데 이부분은 안찍고 넘어갑니다....
너무 오래동안 안되고있어서 미치겠네요 ㄷㄷ
1개의 답변이 있어요!
안녕하세요?
처음부터 질문을 이렇게 하셨으면 간단하셨을텐데 ㅠㅠ 시간이 많이 지체되신거 같아서 안타깝습니다.
질문자께서 전 질문에 첨부하신 코드 토대로 제가 시간을 내서 만들어봤는데 잘 작동합니다. 이 전 질문글에 댓글로 대답드리느라고 제 블로그에 글로 썼는데 아래 링크가서 확인하시거나 github 에서 코드 확인해주세요.
https://blog.naver.com/phsense85/221808296116
https://github.com/kangisworking/serverless-upload-excel-to-s3/blob/master/README.md
[답변추가]
첨부하신 코드도 살펴봤습니다.
문제가
await s3.putObject(uploadParams, async (err, data) => { await console.log('7. s3.putObject callback function'); if (data) { await console.log("Upload Success", data); } else if (err) { await console.log("Error", err); } });위의 부분인데요. 이게 왜 문제냐면.. await 가 처리하는 코드는 Promise객체여야 합니다. s3.putObject 은 Promise 객체가 아니기 때문에 await 붙인다 하더라도 질문자님께서 예상하신 로직처럼 s3.putObject 의 결과를 기다리지 않고 바로 다음 코드로 실행해 버립니다. 그래서 아무리 await 을 붙이셔도 console.log 는 찍히지 않겠죠. ㅠㅠ 저도 전 질문글에 s3.putObject 이 async 처리를 같이 해주는줄 알았는데 (실제로 이렇게 처리해주는 함수들이 많이 있습니다) 어제 실제로 s3.putObject 을 사용해보니 async 처리를 해주지 않아서 await 을 붙여도 넘어가 버리는것을 발견햇습니다.
이게 무슨말이냐면 잘만든 함수들은
s3.putObejct(params, callback) 처럼 사용하면 putObject 실행을 한후에 callback 호출해주고
await s3.putObject(params) 이렇게 사용하면 putObject 이 자동으로 Promise 객체를 리턴해서 async 처리를 해주는 함수들이 있습니다. 저는 s3.putObject 도 이렇게 작동할줄 알고 async await 만 붙여주면 될거라고 예상했는데.. s3.putObject 이 옛날에 만들어서 그런가.. 무조건 Promise 화 해주어야되는걸 발견했습니다. ㅎㅎ 제가 잘못된 댓글로 혼동을 드린거 같아서 죄송스럽네요. mongoose 의 함수들은 거즘 제가 예상한데로 작동합니다.
어쨋든 s3.putObject 을 Promise 화 할려면 Promise 로 s3.putObject 을 한번 싸주면 됩니다.
await new Promise((resolved, rejected) => { s3.putObject(uploadParams, (err, res) => { if(err) return rejected(err) resolved(res) } }이렇게 Promise 객체로 변경해주시면 질문자님께서 원하시는것처럼 작동됩니다. (요게.. Javascript 를 조금 옛날부터 배우신분들은 [callback] -> [Promise] -> [async await] 이런 과정을 배우면서 쉬울수 있는데 만약 처음부터 async await 으로 접근하면 잘 모르실수 있습니다.
저 위의 코드에서 s3.putObject 에 대한 결과를 보고 싶으시면
const result = await new Promise(s3.putObject(........)) console.log('result: ', result)로 보시면 확인할수 있습니다.
[추가 내용]
혹시 몰라.. s3.putObject 을 async 로 사용할수 있는지 검색을 해봤더니 방법이 있었네요 ㅎ
try { const s3Response = await s3.putObject(params).promise(); } catch (e) { console.log(e); }이렇게 s3.putObject 뒤에 promise() 를 붙여주면 s3.putObject 이 promise 객체로 반환되네요. 그러면 async await 를 사용할수 있지요~ 질문자님 덕분에 또 새로운걸 알아갑니다. 수고하세요~~