Synchronous / Asynchronous ??
Synchronous (동기)
-> 명령어의 순서대로 실행

위 코드의 출력은 차례대로 1 2 3 4 가 된다.
Asynchronous (비동기)
-> 명령어의 순서대로 실행되지 않음

위 코드의 출력은 1 2 4 3 이 된다.
setTimeout(function(){console.log(3)}. 5000); 코드는 5초 뒤에 function() 함수를 실행시킨다. 이 때 console.log(4)는 setTimeout 코드를 기다리지 않고 먼저 실행된다.
아래의 그림을 살펴보자

왼쪽은 동기적(Synchronous)으로 실행되는 그림이고, 오른쪽은 비동기적(Asynchronous)으로 실행되는 그림이다.
동기적으로 실행될 경우, 하나의 프로세스가 다른 프로세스를 호출하면 호출된 프로세스의 작업이 끝날 때까지 기다린다.
하지만 비동기적으로 실행되면 다른 프로세스를 호출해도 호출한 프로세스는 가만히 기다리고만 있지 않고, 다음 작업을 이어서 수행한다.
따라서 비동기적으로 실행될 때는 각자의 시간 흐름에 맞춰 병렬적으로 작업이 수행된다.
그러면 언제 비동기적인 처리가 필요할까?
대표적으로 서버와 웹 브라우저가 통신을 할 때,
통신 시간이 얼마나 걸릴 지는 예측할 수 없다. 따라서 통신이 끝날 때 까지 아무것도 하지 않고 기다리는 것보다는 다른 작업을 수행하다가 통신이 끝나면 그 때, 콜백이 호출되어서 기다리던 작업을 이어서 하는 것이 효율적일 것이다.

웹 브라우저에서 검색 키워드를 입력하면 자동완성 목록이 나온다.
키워드를 입력하면 실시간으로 서버와 웹 브라우저 간에 통신이 이루어진다.
이렇게 브라우저와 웹 서버가 페이지 Reload를 하지 않고도 자바스크립트를 이용하여 통신하는 것을 Ajax 라고 한다.
만약 브라우저와 웹 서버가 동기식으로 통신을 하였다면, 통신이 이루어지는 동안 사용자는 아무것도 하지 못했을 것이다. 비동기식으로 통신이 이루어졌기 때문에, 자동완성 내용을 불러오는 통신이 이루어지는 동안에도 사용자는 계속 작업을 할 수 있는 것이다.
웹 브라우저와 웹 서버가 통신을 할 때는 fetch()라는 api를 사용하는데 fetch()는 promise를 사용한다.
간단한 fetch()의 예시를 살펴보자.
fetch('http://example.com/movies.json')
.then((response) => response.json())
.then((data) => console.log(data));
fetch()에 인자로 주소를 준 뒤 실행하면, 웹 서버가 리턴해준 json 데이터를 받아온 뒤 출력한다.
위의 주소는 가짜 주소이므로 JSONPlaceholder 라는 사이트에서 테스트용 주소를 사용해보았다.
JSONPlaceholder에서는 서버를 마련하지 않고 여러 json 형식의 데이터를 받아오는 url을 사용해 REST API을 사용한 통신을 테스트해 볼 수 있다.


/posts 자원의 내용을 사용해보자.

해당 링크로 api 요청을 보내면 화면에 나와 있는 json 형식의 데이터들을 응답으로 받아올 수 있다.
<script>
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((data) => console.log(data));
</script>
코드를 입력 후 확인해보면

json 형식의 데이터들을 받아온 것을 볼 수 있다.


이런 식으로 다른 곳에서 응답을 받아와야 하는 과정이 필요할 경우, 응답을 받아오기까지 얼마나 시간이 걸릴 지 모르기 때문에 비동기적으로 코드가 동작하도록 하는 것이 효율적일 것이다.
fetch() 함수를 더 자세히 살펴보자
fetch() 함수는 Promise 데이터 타입을 리턴해주고, Promise 데이터 타입은 Response 객체를 돌려준다.
해당 코드를 입력해보면
<script>
var fetched = fetch('https://jsonplaceholder.typicode.com/posts');
console.log(fetched);
</script>

fetch()는 Promise 데이터 타입을 리턴해주는 것을 확인할 수 있다.
어떤 함수를 사용할 때 리턴값이 Promise라면 그 함수는 비동기적으로 동작하는 함수일 확률이 굉장히 높다.
그 함수가 리턴하는 값은 거기서 또 then()과 catch() 라는 2개의 메서드를 사용할 수 있다.
then()과 catch()는 모두 콜백함수를 하나씩 받고, 각가의 콜백함수는 모두 파라미터를 하나씩 갖고있다.
fetch()를 통해 실행한 결과가 성공했을 때, then()으로 정의된 콜백함수가 호출된다. 호출된 콜백함수가 결과값을 갖고있다면, 그 결과값을 첫번째 파라미터로 받을 수 있다.
다음과 같이 작성된 코드로 response를 성공적으로 받은 결과를 확인해보자
<script>
fetch('https://jsonplaceholder.typicode.com/posts')
.then(function(response){
console.log('response', response);
})
.catch(function(reason){
console.log('resaon', reason);
});
</script>

응답을 성공적으로 받았고 파라미터로 받은 response를 확인해보면 Response 객체를 반환하는 것을 확인할 수 있다.
fetch()의 리턴값은 Promise인데, 이때 성공적으로 실행됐다면 Promise의 .then() 함수를 통해 response 객체를 전달한다.
이번엔 응답을 받지 못했을(실패한) 경우를 확인해보자.
fetch()를 통해 실행한 결과가 실패했을 때는, catch()으로 정의된 콜백함수가 호출된다. 호출된 콜백함수의 파라미터는 실패한 이유를 반환한다.
<script>
fetch('https://jsonplaceholder.typㄴㅇㄹicode.com/posts')
.then(function(response){
console.log('response', response);
})
.catch(function(reason){
console.log('resaon', reason);
});
</script>
앞에서 작성한 코드의 url에 이상한 값을 추가해주었다.

파라미터로 받은 reason을 확인해보면 다음과 같이 실패 이유를 알 수 있다.
Promise를 사용하는 이유?
-> 비동기적인 작업을 처리할 때, 그 작업이 성공했는지 실패했는지에 대한 처리를 표준화 된 방법을 통해 할 수 있음.
-> 텍스트로 되어 있는 데이터를 자바스크립트에서 사용할 수 있는 자료형으로 변환하여 사용할 수 있음
Promise의 동작 방식
Promise의 구조를 그림으로 확인해보자

PENDING은 결과를 기다리고 있는 상태이고,
결과가 성공하면 RESOLVED 상태가 되고 .then()으로 전달된 함수가 호출된다.
결과가 실패하면 REJECTED 상태가 되고, .catch()로 전달된 함수가 호출된다.
.then()이건 .catch()건 새로운 Promise가 리턴되면 이 Promise로 다시 .then()과 .catch() 처리가 가능한 구조가 되는 것이다.
아래의 코드를 통해 살펴보면
<script>
fetch('https://jsonplaceholder.typicode.com/posts')
.then(function(response){
response.json().then(function(data){
console.log('data', data);
})
})
.catch(function(reason){
console.log('reason', reason);
});
</script>
response.json()은 Promise를 반환한다. 여기서 다시 .then()을 사용해서 json 형식으로 받은 데이터를 출력해볼 수 있다.
.then()이 Promise를 반환하기 때문에 여기서 다시 .then()과 .catch()를 연쇄적으로 사용이 가능한 것이다.
위와 같이 .then()에 이어서 또 .then()이 나오는 방식으로 작성하는 구조를 Nested promise 라고 한다.
위 코드와 같은 동작을 하는 코드를 다른 방식으로 적으면 이렇다.
<script>
fetch('https://jsonplaceholder.typicode.com/posts')
.then(function(response){
return response.json();
})
.catch(function(reason){
console.log('reason', reason);
})
.then(function(data){
console.log('data', data);
});
</script>
이 코드에서는 .then() 안에서 promise를 리턴하고, 그 바깥쪽에서 .then()을 연결해서 사용 가능하다.
이런 구조를 Promise Chaining 이라고 한다.
두 방식 모두 장단점이 있지만 일반적으로 Promise Chaining 방식을 사용한다고 한다.
'JavaScript' 카테고리의 다른 글
[JavaScript] Promise 직접 만들기 (new Promise) (0) | 2022.05.23 |
---|---|
[JavaScript] async & await (0) | 2022.05.23 |
[JavaScript] 자바스크립트 Callback (콜백 함수) (0) | 2022.05.21 |
Synchronous / Asynchronous ??
Synchronous (동기)
-> 명령어의 순서대로 실행

위 코드의 출력은 차례대로 1 2 3 4 가 된다.
Asynchronous (비동기)
-> 명령어의 순서대로 실행되지 않음

위 코드의 출력은 1 2 4 3 이 된다.
setTimeout(function(){console.log(3)}. 5000); 코드는 5초 뒤에 function() 함수를 실행시킨다. 이 때 console.log(4)는 setTimeout 코드를 기다리지 않고 먼저 실행된다.
아래의 그림을 살펴보자

왼쪽은 동기적(Synchronous)으로 실행되는 그림이고, 오른쪽은 비동기적(Asynchronous)으로 실행되는 그림이다.
동기적으로 실행될 경우, 하나의 프로세스가 다른 프로세스를 호출하면 호출된 프로세스의 작업이 끝날 때까지 기다린다.
하지만 비동기적으로 실행되면 다른 프로세스를 호출해도 호출한 프로세스는 가만히 기다리고만 있지 않고, 다음 작업을 이어서 수행한다.
따라서 비동기적으로 실행될 때는 각자의 시간 흐름에 맞춰 병렬적으로 작업이 수행된다.
그러면 언제 비동기적인 처리가 필요할까?
대표적으로 서버와 웹 브라우저가 통신을 할 때,
통신 시간이 얼마나 걸릴 지는 예측할 수 없다. 따라서 통신이 끝날 때 까지 아무것도 하지 않고 기다리는 것보다는 다른 작업을 수행하다가 통신이 끝나면 그 때, 콜백이 호출되어서 기다리던 작업을 이어서 하는 것이 효율적일 것이다.

웹 브라우저에서 검색 키워드를 입력하면 자동완성 목록이 나온다.
키워드를 입력하면 실시간으로 서버와 웹 브라우저 간에 통신이 이루어진다.
이렇게 브라우저와 웹 서버가 페이지 Reload를 하지 않고도 자바스크립트를 이용하여 통신하는 것을 Ajax 라고 한다.
만약 브라우저와 웹 서버가 동기식으로 통신을 하였다면, 통신이 이루어지는 동안 사용자는 아무것도 하지 못했을 것이다. 비동기식으로 통신이 이루어졌기 때문에, 자동완성 내용을 불러오는 통신이 이루어지는 동안에도 사용자는 계속 작업을 할 수 있는 것이다.
웹 브라우저와 웹 서버가 통신을 할 때는 fetch()라는 api를 사용하는데 fetch()는 promise를 사용한다.
간단한 fetch()의 예시를 살펴보자.
fetch('http://example.com/movies.json')
.then((response) => response.json())
.then((data) => console.log(data));
fetch()에 인자로 주소를 준 뒤 실행하면, 웹 서버가 리턴해준 json 데이터를 받아온 뒤 출력한다.
위의 주소는 가짜 주소이므로 JSONPlaceholder 라는 사이트에서 테스트용 주소를 사용해보았다.
JSONPlaceholder에서는 서버를 마련하지 않고 여러 json 형식의 데이터를 받아오는 url을 사용해 REST API을 사용한 통신을 테스트해 볼 수 있다.


/posts 자원의 내용을 사용해보자.

해당 링크로 api 요청을 보내면 화면에 나와 있는 json 형식의 데이터들을 응답으로 받아올 수 있다.
<script>
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((data) => console.log(data));
</script>
코드를 입력 후 확인해보면

json 형식의 데이터들을 받아온 것을 볼 수 있다.


이런 식으로 다른 곳에서 응답을 받아와야 하는 과정이 필요할 경우, 응답을 받아오기까지 얼마나 시간이 걸릴 지 모르기 때문에 비동기적으로 코드가 동작하도록 하는 것이 효율적일 것이다.
fetch() 함수를 더 자세히 살펴보자
fetch() 함수는 Promise 데이터 타입을 리턴해주고, Promise 데이터 타입은 Response 객체를 돌려준다.
해당 코드를 입력해보면
<script>
var fetched = fetch('https://jsonplaceholder.typicode.com/posts');
console.log(fetched);
</script>

fetch()는 Promise 데이터 타입을 리턴해주는 것을 확인할 수 있다.
어떤 함수를 사용할 때 리턴값이 Promise라면 그 함수는 비동기적으로 동작하는 함수일 확률이 굉장히 높다.
그 함수가 리턴하는 값은 거기서 또 then()과 catch() 라는 2개의 메서드를 사용할 수 있다.
then()과 catch()는 모두 콜백함수를 하나씩 받고, 각가의 콜백함수는 모두 파라미터를 하나씩 갖고있다.
fetch()를 통해 실행한 결과가 성공했을 때, then()으로 정의된 콜백함수가 호출된다. 호출된 콜백함수가 결과값을 갖고있다면, 그 결과값을 첫번째 파라미터로 받을 수 있다.
다음과 같이 작성된 코드로 response를 성공적으로 받은 결과를 확인해보자
<script>
fetch('https://jsonplaceholder.typicode.com/posts')
.then(function(response){
console.log('response', response);
})
.catch(function(reason){
console.log('resaon', reason);
});
</script>

응답을 성공적으로 받았고 파라미터로 받은 response를 확인해보면 Response 객체를 반환하는 것을 확인할 수 있다.
fetch()의 리턴값은 Promise인데, 이때 성공적으로 실행됐다면 Promise의 .then() 함수를 통해 response 객체를 전달한다.
이번엔 응답을 받지 못했을(실패한) 경우를 확인해보자.
fetch()를 통해 실행한 결과가 실패했을 때는, catch()으로 정의된 콜백함수가 호출된다. 호출된 콜백함수의 파라미터는 실패한 이유를 반환한다.
<script>
fetch('https://jsonplaceholder.typㄴㅇㄹicode.com/posts')
.then(function(response){
console.log('response', response);
})
.catch(function(reason){
console.log('resaon', reason);
});
</script>
앞에서 작성한 코드의 url에 이상한 값을 추가해주었다.

파라미터로 받은 reason을 확인해보면 다음과 같이 실패 이유를 알 수 있다.
Promise를 사용하는 이유?
-> 비동기적인 작업을 처리할 때, 그 작업이 성공했는지 실패했는지에 대한 처리를 표준화 된 방법을 통해 할 수 있음.
-> 텍스트로 되어 있는 데이터를 자바스크립트에서 사용할 수 있는 자료형으로 변환하여 사용할 수 있음
Promise의 동작 방식
Promise의 구조를 그림으로 확인해보자

PENDING은 결과를 기다리고 있는 상태이고,
결과가 성공하면 RESOLVED 상태가 되고 .then()으로 전달된 함수가 호출된다.
결과가 실패하면 REJECTED 상태가 되고, .catch()로 전달된 함수가 호출된다.
.then()이건 .catch()건 새로운 Promise가 리턴되면 이 Promise로 다시 .then()과 .catch() 처리가 가능한 구조가 되는 것이다.
아래의 코드를 통해 살펴보면
<script>
fetch('https://jsonplaceholder.typicode.com/posts')
.then(function(response){
response.json().then(function(data){
console.log('data', data);
})
})
.catch(function(reason){
console.log('reason', reason);
});
</script>
response.json()은 Promise를 반환한다. 여기서 다시 .then()을 사용해서 json 형식으로 받은 데이터를 출력해볼 수 있다.
.then()이 Promise를 반환하기 때문에 여기서 다시 .then()과 .catch()를 연쇄적으로 사용이 가능한 것이다.
위와 같이 .then()에 이어서 또 .then()이 나오는 방식으로 작성하는 구조를 Nested promise 라고 한다.
위 코드와 같은 동작을 하는 코드를 다른 방식으로 적으면 이렇다.
<script>
fetch('https://jsonplaceholder.typicode.com/posts')
.then(function(response){
return response.json();
})
.catch(function(reason){
console.log('reason', reason);
})
.then(function(data){
console.log('data', data);
});
</script>
이 코드에서는 .then() 안에서 promise를 리턴하고, 그 바깥쪽에서 .then()을 연결해서 사용 가능하다.
이런 구조를 Promise Chaining 이라고 한다.
두 방식 모두 장단점이 있지만 일반적으로 Promise Chaining 방식을 사용한다고 한다.
'JavaScript' 카테고리의 다른 글
[JavaScript] Promise 직접 만들기 (new Promise) (0) | 2022.05.23 |
---|---|
[JavaScript] async & await (0) | 2022.05.23 |
[JavaScript] 자바스크립트 Callback (콜백 함수) (0) | 2022.05.21 |