Asynchronous Programming
동기식 처리모델은 직렬식 task를 처리한다. 즉, 하나의 task를 처리하고 있으면 다음 task는 앞에 진행중인 task를 처리하기 전까지 계속 대기하는 형태로 진행이되고, 이 과정에서 blocking 이 일어나게된다.
동기 프로그래밍 방식은 하나의 request가 들어오게 되면, 하나의 함수가 다른 함수를 요청했을 때 해당 요청이 완료 되어야지만 다음 스텝으로 넘어갈 수 있다.
실제로 유저 입장에서 본다면 해당 request가 마치 멈춰있는 듯한 느낌을 받을 수 있다.
반대로 비 동기식 처리모델은 특정 요청에 response를 기다리지 않고 다음 작업을 이어서 진행하되, 특정 요청의 event callback으로 response를 처리하는 방식이다. 비 동기식 처리모델은 읽는 시점과 쓰는 시점이 다를 수 있다.
단, 비동기 처리 방식은 request 순서를 보장할 수 없고, task들이 중첩으로 n개가 들어왔을 때, 각 task들의 처리시간을 파악할 수 없기에 공용메모리 데이터에 대해 이슈가 발생할 수 있다.
그래서 예를들어 각 task마다 고유 key를 지정하여 하나의 task의 대한 결과를 산출하여야 한다.
비 동기 프로그래밍의 순차처리
비 동기 프로그래밍에서의 순서를 보장하기 위해서는 Callback 을 이용하여 순차처리가 가능하다.
javascript 기반의 언어에서는 promise 객체를 통해 비동기 프로그래밍을 좀 더 간결하게 구현할 수 있다.
promise는 4가지 상태를 제공한다.
상태의미
pending | 비동기 처리가 수행되지 않은 상태 |
fulfilled | 비동기 처리가 수행된 상태(성공) |
rejected | 비동기 처리가 수행된 상태(실패) |
settled | 비동기 처리가 수행된 상태(성공 또는 실패) |
Promise 객체 생성
// Promise 객체의 생성
const promise = new Promise((resolve, reject) => {
// 비동기 작업을 수행한다.
if (/* 비동기 작업 수행 성공 */) {
resolve('result');
}
else { /* 비동기 작업 수행 실패 */
reject('failure reason');
}
});
프로미스 체이닝을 통한 순서를 보장할 수 있는 프로그래밍
promise.
then((result:any) => {
return Promise.resolve(result);
})
.then((result:any) => {
return Promise.resolve(result);
})
.then((result:any) => {
return Promise.resolve(result);
])
.catch((err) => {
//error
})
Serializer
비 동기 task를 큐의 형태로 담아서 순서를 보장하게 할 수 있다.
예를 들면, 인메모리상 데이터 영역에 큐 형태의 배열을 담아두고 비 동기 task들을 해당 배열에 enqueue 하고 dequeue하면서 task를 실행하면 전역적으로 task의 순서를 보장할 수 있게 된다.