[TIL] API통신과 try...catch

JIEUN YANG·2022년 11월 22일
0
post-thumbnail

API통신의 response값을 특정 컴포넌트의 props 로 전달할 때, props 데이터가 실시간으로 변경되지 않는 이슈가 발생하였다.
정확히 말하자면, 데이터가 한타임씩 씹힌 채로 하위컴포넌트를 랜더링하는 상황이었다.

console.log() 로 확인해보니 데이터는 정상적으로 들어있었으나, 컴포넌트로 넘어온 props.printData 는 이전 console.log에서 찍힌 값이 출력되고 있었다. 이러한 상황이 발생한 이유로 크게 2가지를 의심해보았고, 한가지 방법으로 해결할 수 있었다.


// 상위 컴포넌트
<template>
	<print-page :print-data="state.printData" />
</template>


<scrip setup>
import Printpage from '@/printView/printPage'

const saveRowList = async () => {
  store.commit('loadingStart')

  try {
    const { data } = await Api.save(state.rowData)
    state.printData = data
    console.log(state.printData) // printed what i expexted
    printJS(state.printStyle) //화면 프린트 실행 코드
  } catch (e) {
    console.log(e)
  } finally {
    store.commit('loadingEnd')
  }
}
<script>

1. 하위 컴포넌트에서 props 데이터를 즉시 감지하지 못함.

-> 상위에서 넘겨준 props 데이터를 state 변수가 computed로 감지하도록 수정

//하위 컴포넌트

<template>
	<div>{{state.propsData}}</div>
</template>


<scrip setup>
import {reactive, computed} from 'vue'

const state = reactive({
	propsData : computed(()=> props.printData)
})

const props = definedProps({
	printData : {
    	type : Object,
        default : () => {
        	return {}
        }
    }
})

<script>

** 하지만, 동일한 이슈가 지속되었고 다른 방법을 찾아보았다.


2. 상위 컴포넌트에서 API통신의 response가 완전히(?) 응답했을 때, props로 넘길 데이터를 할당

-> try...catch 문법을 활용하여 코드를 동기적으로 실행한 뒤 finally 구문에서 데이터 할당

//상위 컴포넌트

<script setup>

const saveRowList = async () => {
  store.commit('loadingStart')

  try {
    const { data } = await Api.save(state.rowData)
    state.printData = data
    
  } catch (e) {
    console.log(e)
    
  } finally {
    printJS(state.printStyle) // --> 코드 위치 변경
    store.commit('loadingEnd')
  }
}
<script>

** 이슈가 해결되었다. 아마도, 시점차이로 인해 하위컴포넌트가 전달받은 props데이터를 실시간으로 반영하지 못했던 게 원인이었던 듯 싶다.




'try...catch' 정의

try...catch 문은 에러발생 시, 스크립트가 죽었을 때 화면이 비정상적으로 렌더링 되는 것을 방지하고 사용자에게는 상황에 어울리는 UI를 제공할 수 있는 문법이다.


'try...catch' 문법

  1. try...catch
  2. try...finally
  3. try...catch...finally

1. try {} 블록의 코드가 실행된다. 에러가 없으면 try {} 블록의 코드 전체가 실행되고, catch {} 은 건너뛴다. 만약, 에러가 있다면 try {} 블록의 코드 실행이 중단되고, catch {} 블록으로 넘어가 에러 객체를 반환한다.

2. try {} 블록의 코드가 실행된다. try {} 블록의 코드가 모두 실행된 후에 finally {} 블록의 코드가 실행된다.

3. 1번의 경우와 동일하며, try {} 혹은 catch {} 둘 중 어느 쪽이 실행되는지와 무관하게 마지막으로 finally {} 구문이 실행된다.

try...catch구문은 동기적으로 실행되기 때문에, try {} 블록 내의 모든 코드가 에러없이 실행된 후에(API 통신의 response 값이 정상적으로 할당) finally(생략가능) 블록이 순차적으로 실행되므로 finally {} 블록에서 프린트로직을 실행시킨다면,

  • try 문에서 props 로 전달할 데이터를 정상적으로 할당한다.
  • try 문의 실행이 종료된 후 finally문이 실행되어 데이터가 정상 프린트 된다.

이 외에도, nextTick으로 DOM이 update될 때까지 기다린 뒤에 화면을 그리도록 하는 방법도 존재한다. 따라서, 다음 포스팅은 동일한 이슈를 nextTick()으로 해결하는 내용을 작성하도록 하겠다.




참조

mdn-try...catch

https://ko.javascript.info/

profile
violet's development note

0개의 댓글