반응형
Promise - async, await 범위 설정하기
아래 글은 async와 await 범위 설정에 따라 결과값이 달랐던 부분을 기록하기 위한 글이다.
두 코드 모두 HTML5 Canvas에서 생성된 이미지를 블롭(blob) 형태로 만들어서 AWS S3에 업로드하는 기능을 수행한다.
수정 전 (uploadMaskingImageFile 함수)
// canvas 위의 masking된 이미지를 s3에 업로드하는 함수
const uploadMaskingImageFile = async () => {
const image = new Image();
if (canvasRef.current && imageData) {
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
if (context) {
canvas.toBlob(async (blob) => {
if (blob) {
const file = new File([blob], 'masking.png', { type: blob.type });
const maskingPath = await onFileUpload(file, () => { }); // s3로 파일을 업로드
let imageInformation: ImageInfo = {
id: undefined,
parentId: null,
prompt: inputPrompt,
image: maskingPath!
};
return imageInformation;
});
}
} else {
alert("마스킹된 이미지가 없습니다.");
}
};
- canvasRef가 존재하고 imageData가 존재하는지 확인한다.
- canvas 및 2D 컨텍스트를 얻어온다.
- Canvas를 블롭(blob) 형태로 변환한다.
- 블롭을 이용하여 새로운 File 객체를 생성한다.
- 생성된 파일을 AWS S3에 업로드하기 위해 onFileUpload 함수를 호출한다.
- 업로드된 파일 경로를 변수 maskingPath에 저장한다.
- 이미지 정보를 담는 객체를 생성하고, 이 정보를 반환한다.
문제가 없어 보이는 코드이지만, 계속해서 maskingPath이 undefined이 나왔다.
수정 후 (uploadMaskingImageFile 함수)
// canvas 위의 masking된 이미지를 s3에 업로드하는 함수
const uploadMaskingImageFile = async () => {
if (canvasRef.current && imageData) {
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
if (context) {
const _blob: Blob = await new Promise<Blob>(async (res, rej) => {
canvas.toBlob(async (blob) => {
if (blob) {
res(blob);
return;
}
rej(new Error('Failed to create blob.'));
});
});
const file = new File([_blob], 'masking.png', { type: _blob.type });
const maskingPath = await onFileUpload(file, () => { }); // s3로 파일을 업로드
let imageInformation: ImageInfo = {
id: undefined,
parentId: null,
prompt: inputPrompt,
image: maskingPath!
};
return imageInformation;
} else {
alert("마스킹된 이미지가 없습니다.");
throw new Error("Canvas context is not available.");
}
} else {
alert("마스킹된 이미지가 없습니다.");
throw new Error("Canvas or image data is not available.");
}
};
- canvasRef가 존재하고 imageData가 존재하는지 확인한다.
- canvas 및 2D 컨텍스트를 얻어온다.
- canvas.toBlob 메소드를 사용하여 Canvas를 블롭(blob) 형태로 변환한다. 이 부분에서 Promise를 사용하여 블롭 생성 과정을 감싸고 있다.
- 생성된 블롭을 이용하여 새로운 File 객체를 생성한다.
- 생성된 파일을 AWS S3에 업로드하기 위해 onFileUpload 함수를 호출한다.
- 업로드된 파일 경로를 변수 maskingPath에 저장한다.
- 이미지 정보를 담는 객체를 생성하고, 이 정보를 반환한다.
문제는 blob이었다.
수정 전 코드에서 canvas.toBlob 메소드를 사용하여 Canvas를 블롭(blob) 형태로 변환하는 과정에서 문제가 있었다.
수정 전의 코드에서 async/await를 걸어서 문제없이 처리했다고 생각했지만, blob 형태로 변환하는 과정 역시도 비동기적으로 처리해도 되는지, 동기적으로 처리해도 되는지에 대해 고려해야하는 부분이었다.
이를 해결하고자 canvas.toBlob 부분을 Promise와 async/await를 사용하여 더 명시적으로 처리함으로써 해결할 수 있었다.
결론적으로, 핵심은 한 코드 내에서 비동기적으로 처리되지 않아야한다면 한 번에 async/await로 감싸지말아야한다는 것이다.
반응형
'Development > Javascript | Typescript' 카테고리의 다른 글
[TS|TIP] 회전된 사각형을 내접하는 사각형(BoundingBox) 구하기 (0) | 2024.07.24 |
---|---|
[Javascript] 직렬화(Serialize), 역직렬화(Deserialize) (1) | 2024.03.17 |
[Typescript] Typescript란? Typescript가 Javascript로 변해야하는 이유는? (0) | 2023.05.24 |
[Javascript] 문자열의 마지막 문자 가져오기 (0) | 2023.05.20 |
[Javascript] 문자열을 숫자 배열로 변환하는 방법 - split(",").map(Number) (0) | 2023.04.20 |