자바스크립트에는 동기, 비동기라는 단어가 있다.
먼저 이런식으로 콘솔을 1부터 4까지 찍으면 당연히 위에서 아래로 순서대로 실행이 된다.
이런식으로 실행 되는 것을 동기적으로 실행 된다라고 부른다.
그런데 이중에서 요 세번 째 행을
이런식응로 setTimeout이라는 함수를 사용하여 5초 뒤에 실행이 되도록 만들었다.
이 코드를 실행하게 되면
1,2,4는 바로 먼저 실행이 되고 5초 뒤에 3이 실행되어 콘솔이 찍히는 것을 확인할 수 있다.
생각해보면 3이 실행될때 5초를 기다리지 않고 우선은 4가 먼저 실행이 되었다. 그리고 5초 뒤에 저 콜백 함수가 자바스크립트에 의해 실행이 되고 마지막에 콘솔 3이 찍힌것이다. 즉 저 fucntion코드는 메인이 되는 실행 순서와는 별개로 독립적인, 자기 시간표에 따라 동작을 하고 있다.
이렇게 프로그램이 병렬적으로 실행 되는 방식을 비동기적이다라고 한다.
위 이미지는 동기 비동기 방식을 설명한 이미지이다.
먼저 동기방식은 명령의 실행이 끝날때까지 다음 명령이 실행되지 않고 기다린다. 반면 비동기는 비동기적인 명령을 동시에 실행시켰다고하면 각자 자기의 시간표에 따라 실행이 된다. 이 동기적 방식의 좋은점은 순차적으로 실행되는 것이기때문에 어떻게 실행되는것인지 파악하기 쉽다. 반면 비동기적으로 하면 동시에 여러 일을 하기때문에 다소 혼란스럽지만 훨씬 더 빨리 처리가 가능하다.
비동기적 방식을 쓰는 경우는 어떤 명령을 실행할 때 그 명령이 언제 끝날지 예측하기 어렵거나 주가 되는 작업이 아닐때 비동기적 방식을 많이 사용한다.
서버와의 통신이 그렇다. 통신이 언제 끝날지 모르기 때문에 통신이 끝날때까지 아무것도 못하는것 보단 다른 일을 하고 있다가 통신이 끝날 때 콜백이 호출이 되면서 필요한 작업들을 처리하면 더 효율적으로 처리할 수 있게 된다.
이번에는 웹서버와 통신을 하는 fecth()라는 함수를 살펴볼 것이다.
기본 문법은 이렇게 되고 저 url과 통신하여 그 결과 데이터를 myJson에 json 형태로 담아 가지고 온다. https://jsonplaceholder.typicode.com/ 사이트에 접속하여 json데이터를 통신으로 과져와 보자
이런식으로 주소를 요청하면 사진과 같은 데이터를 받을 수 있다.
위와 같이 작성 후 콘솔을 눌러보면?
이렇게 데이터들을 다 받아왔다.
우리는
이런식의 json으로 된 데이터들을 위의 자바스크립트 코드로 자바스크립트 객체로 다 가지고 온 것이다.
자 그럼 여기에
fetch함수 위 아래로 콘솔 1과 2를 찍어 보았는데 결과는 어떻게 나올까?
1,2가 먼저 찍히고 통신이 끝난 뒤 fetch함수의 콜백 함수가 호출이 된다. 자 이때 우리가 사용한 then이라고 하는 것을 바로 promise라고 한다.
이 fetch함수를 뜯어보면 어떤 값을 리턴할 것인데 그게 뭐냐면
어떤 Promise 데이터를 리턴한다고 되어있는데 이 타입은 response object를 돌려준다고 되어 있다.
확인을 위해 이 fetch함수를 변수에 넣어 콘솔로 찍어보면
Promise라는걸 리턴한 것을 확인할 수 있다.
어떤 함수의 리턴 값으로 Promise가 리턴이 되면 이건 비동기적으로 동작하는 함수일 가능성이 매우 높다고 한다.
이 Promise로 리턴을 받으면 두개의 함수를 사용할 수 있게 되는데 하나는 then, 하나는 catch이다
둘다 콜백함수를 가지고 있고 파라미터를 하나씩 갖는다. 여기서 then은 언제 호출이 되냐면 fetch함수가 성공했을 때 then으로 전달된 콜백함수가 호출되도록 약속되어있다. 그리고 그 콜백함수가 호출 되면서 그 결과 값이 있다면 첫 번째 파라미터로 받을 수 있다. 만약에 실패하게 되면 catch로 전달된 콜백함수가 실행이 되고 똑같이 결과 값을 첫 번째 파라미터로 받을 수 있다.
then으로 전달된 함수를 찍어보면
이렇게 response라는 객체로 받은 것을 확인할 수 있다.
아까 fetch함수의 문서에서 리턴 값을 다시 확인해보면
이거였는데 여기서 resolves라는건 성공적으로 실행이 되었다라는 뜻으로 생각하면 된다.
그렇기에 성공해서 then이 실행되어 response를 받아온 것
다음은 주소에 그냥 오타를 하나 넣어 일부러 실패를 해 보았는데
이렇게 catch에 있는 콜백함수를 탄것을 확인할 수 있다. 이러한 Promise를 사용하는 첫 번째 이유는 비동기적인 어떤 작업을 성공할 때 이 작업이 성공했는지 실패했는지를 표준화 된 방식으로 처리할 수 있다는 것이다.
결국 처음에 했던 코드로 이렇게 체이닝하여 연결을 할 수 있다.
이 result로 가져온 데이터 자체는 일반적인 텍스트이다. 이 텍스트를 이용해서 자바스크립트에서 가공하고 처리하는 건 쉽지 않다. 하지만 이 정보들을 자바스크립트의 데이터 타입으로 바꿀 수 있다면 훨씬 작업하기 쉬워진다. 그렇기에 이 result가 갖고 있는 함수중에 result.text()라던지 reseult.json() 이런식의 함수가 있는데 json();으로 하면 https://jsonplaceholder.typicode.com/posts 이 주소로 요청한 데이터들이 json타입이라는 것을 자바스크립트에게 우리가 알려 주는것이다. 그러면 이 웹브라우저는 json데이터 타입에 맞게 이 데이터 타입을 해석해서 자바스크립트 타입으로 돌려준다.
이렇게 또 result.json()으로 찍어서 뭘 리턴하는지 보면 Promise를 리턴한다. 근데 아까 위에 json타입으로 알려주었는데도 바로 json데이터가 나오지 않고 Promise라고 뜨는것은 아직 데이터를 다 받지 않은 상태여서 그렇다.( header만 도착하고 body부분은 오지않음) 그래서 다시 체이닝을 통하여 작업을 하는것(데이터가 다 도착한 이후)
그럼 여기서 result.json()은 Promise니까 또 다시 then()과 catch()를 쓸 수 있는것이다.
이런식으로 다시 then 걸어주면
데이터 값으로 저 사이트의 json데이터들을 가지고 왔다.
이 Promise를 사용하게 되면 그 즉시 펜딩상태 (대기중)가 된다 이 결과가 성공하면 then으로 전달된 함수가 호출(resolved 상태) 실패하면 catch함수로 들어간다. then이건 catch건 새로운 Promise를 리턴하면 다시 펜딩 상태가 되고 이게 반복되는것이다.
이 글은 유튜브 생활코딩을 보며 공부한 내용을 기록한 게시글입니다.
참고 : https://velog.io/@hayyim0626/TIL-Promise
참고 : https://jsonplaceholder.typicode.com/
참고 : https://velog.io/@dorazi/Asynchronous-VS-Synchronous