Hyebin‘s blog

자바스크립트의 sync / async

자바스크립트는 일방적으로 동기방식이다. 윗줄부터 차례로 코드가 실행 된다.

 

하지만 sync / async 함수를 사용하면 비동기적으로 코드실행이 가능하다.

순차적 실행이 아닌, 완료되면 실행이 된다.

(ajax, 이벤트리스너, setTimeout 이런 함수들을 쓸 때 그런 현상이 일어남)

 

예를들어

console.log(1+1)
axios로 get요청하고나서 console.log(1+2) 실행해주셈
console.log(1+3)

이럴 경우에는

2, 4, 3 이 순서대로 출력이 된다.

3을 출력하는 코드가 asynchronous 처리를 지원하는 코드인데, 3을 출력할 때 오래걸리면 완료될 때 까지 잠깐 보류했다가 다른 코드를 먼저 실행시킨다는 소리이다.

심지어 ajax요청이 0.00초 걸려도 4가 먼저, 그 다음 3이 출력된다. 물리적으로 잠깐 처리가 보류되어서 그렇다! (신기하다)

리액트의 setState 함수 특징

리액트로 state 만들 땐

function App(){
  let [name, setName] = useState('kim')
}

setName을 사용하시면 name이라는 state를 자유롭게 변경가능

setName('park') 이런 식으로 하면 변경!

 

근데 문제는 변경함수들은 전부 비동기적으로 처리된다.

이럴 경우 예상 치 못한 문제가 발생할 수 있다.

 

function App(){
  let [count, setCount] = useState(0);
  let [age, setAge] = useState(20);

  return (
    <div>
      <div>안녕하십니까 전 {age}</div>
      <button>누르면한살먹기</button>
    </div>
  )

}

버튼을 누를 때마다

 

(1) count라는 state를 +1 (버튼누른 횟수 기록용)

(2) age라는 state도 +1

(3) count 가 3 이상이면 더 이상 age라는 state를 1 더하지 말도록

버튼 3번 이상 누르면 (count가 3 이상이면) 나이를 그만더하라는 기능으로 22살에서 멈춰야한다.

그러면

<button onClick={()=>{

  setCount(count+1);
  if ( count < 3 ) {
    setAge(age+1);
  }
         
}}>누르면한살먹기</button>

이런식으로 코드를 짜면 되는데 23까지 증가한다. 분명 22까지 증가하도록 코드를 짰는데 왜 이런 결과가 나올까?

 

 

이유는 async라는 특징 때문이다.

 

 

 

state 변경함수는 async(비동기방식) 하게 처리되는 함수기 때문에 완료되기까지 시간이 오래걸리면 제쳐두고 다음 코드를 실행 시킨다.

 

① 버튼을 세번째 누르면 setCount(count+1); 이걸 실행해서 count를 3을 만들어준다.

② 근데 count를 3으로 만드는건 오래걸리니까 제껴두고 if ( count > 3 ) {} 이걸 실행한다.

③ 이 때 count는 아직 2라서 if문 안의 setAge(age+1)이 잘 동작하고 있는것

 

 

결론 : setCount()가 async 함수라서.

async함수는 오래걸리면 제껴두고 다음 줄 코드부터 실행

 

해결 방법 ? sync스럽게, 순차적으로 실행하고 싶을 때 해결책은 useEffect이다.

 

import React, { useState, useEffect } from 'react';
import './App.css';

function App() {
let [count, setCount] = useState(0);
let [age, setAge] = useState(20);
useEffect(()=>{
  if(count !=0 && count<3){
//처음 페이지 로드시 useEffect 실행을 막는 코드로
//count가 0이 아닐 때만 실행하라고 조건을 추가
    setAge(age+1)
  }
},[count])
//뒤에다가 [] 대괄호안에 state를 집어넣으면 state가 변경되면 이 코드 실행해주세요~ 라는 뜻
  return (
    <div>
      <div>안녕하십니까 전 {age}</div>
      <button onClick={()=>{
        setCount(count+1);
      }
      }>누르면한살먹기</button>
    </div>
  )
}

export default App;
profile

Hyebin‘s blog

@hyebin Lee

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그