await과 Promise.then 과연 잘 알고있는지?

Tags
 

요약

await 은 진짜 기다린 후에 다음 스텝을 이어가는데,
Promise.then.catch 이렇게 체인으로 해버리면 이 체인 이 전체를 묶음으로 던지고, 뒤에 코드들을 쭉 실행시킨다.
제대로 알고 쓰자.
 
 
try{ }catch (error) { }finally{ }
 

잘 될 거 같지?

// 다운받은 펌웨어를 펌웨어로 보내는 함수 const writeFirmware = useCallback( async (fileSize: number): Promise<void> => { await hardwareController.doUpdate({ position: 0, fileSize, onChangeProgress: onProgressChange, onFinish: handleFinishUpdate, }); }, [handleFinishUpdate, hardwareController, onProgressChange], ); // 다운로드 및 펌웨어 쓰기를 진행하는 함수 const updateFirmware = useCallback(async (): Promise<void> => { try { hardwareController.setIsUpdating(true); hardwareController.clearCommandQueue(); const { fileSize } = await downloadFirmware(); await writeFirmware(fileSize); } catch (error) { setIsError(true); } finally { hardwareController.setIsUpdating(false); setDeviceState((previousState) => { return { ...previousState, canUpdateFirmware: false, }; }); } }, [downloadFirmware, hardwareController, writeFirmware]);
 

문제를 만들었던 Promise.then

public async doUpdate({ position, fileSize, packetNumber = 1, NAQCount = 0, onChangeProgress, onFinish, }: { position: number; fileSize: number; packetNumber?: number; NAQCount?: number; onChangeProgress?: (progress: number) => void; onFinish?: () => void; }): Promise<void> { fs.read( LOCAL_FIRMWARE_PATH, FIRMWARE_UPDATE_BUFFER_SIZE, position, 'base64', ) .then(async (base64) => { const decodedFirmwareBytes = decode(base64); const numberedResult: number[] = []; // 펌웨어 파일 데이터를 숫자배열로 변환 for (let i = 0; i < decodedFirmwareBytes.length; i += 1) { numberedResult.push(decodedFirmwareBytes.charCodeAt(i)); } // 더이상 읽을 게 없다면, 이전 데이터 바이트 전송이 마지막 전송이었다는 뜻이므로 완료 처리 if (numberedResult.length === 0) { RNSerialport.writeHexString(getPadHexDigits(XMODEM_1K.EOT, 2)); this.setIsUpdating(false); onFinish?.(); return; } // 전송 크기보다 작다면 나머지는 0xff로 채워서 보냄 if (numberedResult.length < FIRMWARE_UPDATE_BUFFER_SIZE) { for ( let i = 0; i < FIRMWARE_UPDATE_BUFFER_SIZE - decodedFirmwareBytes.length; i += 1 ) { numberedResult.push(0xff); } // 전송크기보다 작은 경우는 마지막 부분을 읽었을 때 뿐이므로, 전송 후 완료 처리 const sendResult = await this.sendFirmwareBytesToHardware( numberedResult, packetNumber, ); if (sendResult[0] === XMODEM_1K.NAQ) { throw new Error('NAQ'); } RNSerialport.writeHexString(getPadHexDigits(XMODEM_1K.EOT, 2)); this.setIsUpdating(false); onFinish?.(); return; } // 읽은 크기와 전송 크기가 동일하다면 전송이 마무리되지 않았다는 뜻이므로 전송 후 재귀호출 if (decodedFirmwareBytes.length === FIRMWARE_UPDATE_BUFFER_SIZE) { const sendResult = await this.sendFirmwareBytesToHardware( numberedResult, packetNumber, ); if (sendResult[0] === XMODEM_1K.NAQ) { throw new Error('NAQ'); } // 재귀 호출 this.doUpdate({ position: position + FIRMWARE_UPDATE_BUFFER_SIZE, fileSize, packetNumber: packetNumber + 1, onChangeProgress, onFinish, }); onChangeProgress?.( 50 + Math.floor(((position + 2048) / fileSize) * 50), ); } }) .catch((error) => { // NAQ가 10회 넘었다면 더이상 진행하지 않고 종료함. if (NAQCount >= 10) { return; } // NAQ라면 해당 순번을 다시 전송함 if (error.message === 'NAQ') { this.doUpdate({ position, fileSize, packetNumber, NAQCount: NAQCount + 1, onChangeProgress, onFinish, }); } }); }