jongpak / dev-tip

My Dev tips
1 stars 0 forks source link

자바스크립트에서의 비동기 통지 #10

Open jongpak opened 4 years ago

jongpak commented 4 years ago

비동기작업의 완료 통지

1. 콜백

비동기 작업이 완료되었을때 수행될 동작을 함께 넘기는 방법

function doAsyncTask(callback) {
    // 무언가 수행한다
    setTimeout(funtion() {
        callback('success');
    }, 3000);
}

doAsyncTask(function(result) {
    console.log('Result: ' + result);
});

error-first pattern

오류여부를 콜백함수에 알려줘야하는데, 오류여부를 콜백함수의 가장 첫 인자로 넣어주는 패턴

콜백 지옥

한두개의 콜백 depth면 상관없는데.. 비동기작업의 depth가 길어질수록 지옥...

2. Promise

완료되었을때 콜백을 '수행'하는 것이 아니라 Promise라는 매개체를 이용함. 이벤트드리븐과도 유사하고, 스트림처리와도 유사함. 핵심은 '중간 매개체'를 이용한다는 것.

Promise는 resolve와 reject를 파라미터로 받는데, 이것은 각각 결과전달와 오류여부를 전달하기위한 것이다. 즉, 기존 콜백의 error-first 패턴과 같은 꼼수(라고 해야하나..)없이도 오류처리를 명확하게 분리할수 있다.

function doAsyncTask() {
    return new Promise(function(resolve, reject) {
        // 무언가 수행한다
        setTimeout(function() {
           // 완료가 되면 통지한다
            resolve('success');
        }, 3000);
    });
}

// 반환되는 promise 를 통해 비동기 작업이 완료되었을때 통지받을수 있다
var result = doAsyncTask();
result.then(function(data) {
    console.log(data);
});

3. async/await

기본적인 모델은 Promise와 동일하되, 플랫폼에서 이것을 편하게 사용할수 있도록 한것.

async 함수의 반환값

async 함수의 반환값은 Promise 다

async function myAsyncFunc() {
    return 'OK';
}

console.log(myAsyncFunc());

즉, async 함수는 Promise를 반환하는 함수다. return 되는 값은 내부적으로 Promise로 감싸서 반환된다. (일종의 sugar syntax로 볼수있음)

await를 쓰면...

await를 쓰면 내부적으로 Promise가 완료될때까지 해당 context의 실행을 잠시 멈추고(=제어권을 내려놓고) 이벤트루프 내 다른 작업을 수행한다. 그러다가 Promise가 완료되면 해당 context를 다시 실행한다.

단일스레드에서 이것이 어떻게 가능한가? 싶겠지만.. 병렬성이 아닌 동시성 관점에서 생각해보자. 이해하기 어렵다면 일종의 시분할 멀티task라고 이해하면 쉬우려나..

function doAsyncTask() {
    return new Promise(function(resolve, reject) {
        // 무언가 수행한다
        setTimeout(function() {
           // 완료가 되면 통지한다
            resolve('success');
        }, 3000);
    });
}

console.log('Result = ' + await doAsyncTask());

async, await 삽질을 안하려면 Promise도 잘 알아야한다

왜냐하면 근간이 Promise이고, 위 예제와 같은 timer 같은 작업에서 Promise를 반드시 써야할수 밖에 없는 상황은 분명이 생긴다