-
Asynchronous & PromiseNote 2020. 11. 10. 21:48
동기(synchronous)와 비동기(Asynchronous)
커피 주문의 예제로 알아보는 동기와 비동기의 차이 출처: PoiemaWeb
커피숍의 대기열에 줄을 서 있는 손님이라고 생각해보자. 앞 손님이 커피를 주문하고, 주문한 커피를 받을 때까지, 줄에 서 있는 손님은 주문조차 할 수 없다면 그 커피숍은 가지 않을 것이다. 이를 blocking이라고 부른다. 동기적(a)인 작업에 따라 이후 작업이 "막히게 된 것"을 말한다. 반면 비동기적(b)인 작업은 앞 손님이 커피를 주문하고, 주문한 커피를 받기 전에도 이후에 온 손님이 주문을 할 수 있는 것을 말한다. 앞에 작업이 처리되지 않더라도 그 이후 작업들이 처리될 수 있는 것을 말하는 것이다.
동기(synchronous)
동기는 요청을 보낸 후 응답을 받아야 다음 동작이 이루어지는 방식.
모든 일은 순차적으로 실행이 되고 어떤 작업이 실행 중이면 다음 작업은 대기하게 된다.
비동기(Asynchronous)
서버로부터 데이터를 받아오는 앱을 만든다고 하면, 서버에서 데이터를 받아 처리해야 할 것이다. 하지만 비동기로 처리하지 않고 동기적으로 이를 처리한다면 데이터를 받아오기까지 기다린 다음에 앱이 실행이 될 것이고 서버에서 가져오는 데이터의 양이 늘어나면 늘어날수록 앱의 속도는 느려지게 되는 것이다. 데이터를 가져오기까지 앱이 대기하는 상태가 되는 것이다. 이런 사용자들의 불편함을 없애기 위해 데이터를 수신하는 코드와 페이지를 표시하는 것 등을 비동기적으로 처리해야 하는 것이다.
Promise
프로미스는 자바스크립트 비동기 처리에 사용되는 객체이다. 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타낸다.
Promise states
-
pending(대기): 이행하거나 거부되지 않은 초기 상태
-
fulfilled(이행): 연산이 성공적으로 완료된 상태
-
rejected(거부): 연산이 실패한 상태
Pending(대기)
아래와 같이 메서드를 호출하면 대기 상태가 된다.
new Promise()
메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject이다.
new Promise(function(resolve, reject) { .. .. })
Fulfilled(이행)
콜백 함수의 인자를 실행하면 이행 상태가 된다.
new Promise(function(resolve, reject) { resolve() })
이행 상태가 되면 then()을 사용하여 결과 값을 받을 수 있다.
const lucky = () => { return new Promise(function(resolve, reject) { let number = 77 resolve(number) }) } lucky().then((luckyNumber) => { console.log(luckyNumber) }) 77 Promise {<fulfilled>: undefined}
Rejected(거부)
프로미스 객체를 생성하고 콜백 함수 인자로 reject를 호출하면 거부 상태가 된다.
new Promise(function(resolve, reject) { reject() })
거부 상태가 되면 거부된 이유를 catch()로 받을 수 있다.
const lucky = () => { return new Promise(function(resolve, reject) { reject(new Error("failed!!!")) }) } lucky().then().catch((error) => { console.log(error) }) Error: failed!!! at <anonymous>:3:12 at new Promise (<anonymous>) at lucky (<anonymous>:2:10) at <anonymous>:7:1 Promise {<fulfilled>: undefined}
Promise.all
순회 가능한 객체에 주어진 모든 프로미스가 이행한 후 Promise를 반환한다.
const promise1 = Promise.resolve(22); const promise2 = 33; const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 500, 'hello'); }); Promise.all([promise1, promise2, promise3]).then((value) => { console.log(value); }); (3) [22, 33, "hello"]
aync / await
함수 정의 앞에 async 키워드를 사용하면 함수 내에 await를 사용할 수 있다. 프로미스를 await 할 때 함수는 프로미스가 결정될 때까지 방해하지 않는 방식으로 일시 중지된다. 프로미스가 이행되면 값을 돌려받고, 프로미스가 거부되면 거부된 값이 반환된다. 프로미스에 익숙하지 않은 사람으로서는 훨씬 더 읽기 쉬워진다.
function lucky() { return new Promise(function(resolve, reject) { let number = [77] resolve(number) }); } async function luckyNumber() { let result = await lucky() console.log(result) } luckyNumber() [77] Promise {<fulfilled>: undefined}
URL을 가져와서 응답을 텍스트로 로그 하려는 경우
1) 프로미스를 사용하는 방법
function logFetch(url) { return fetch(url) .then(response => response.text()) .then(text => { console.log(text); }).catch(err => { console.error('fetch failed', err); }); }
2) 비동기 함수를 사용하는 방법
async function logFetch(url) { try { let response = await fetch(url); console.log(await response.text()); } catch (err) { console.log('fetch failed', err); } }
'Note' 카테고리의 다른 글
node.js, module (0) 2020.11.16 HTTP 프로토콜 (0) 2020.11.12 Ajax, SPA (0) 2020.11.09 undefined, null, undeclared (0) 2020.10.29 OOP(Object Oriented Programming) (0) 2020.10.28 -