Dog foot print

[javascript] 동기와 비동기 본문

Javascript

[javascript] 동기와 비동기

개 발자국 2019. 7. 2. 22:02

콜백 이후로 포스팅 난이도가 상승했다. 그렇지만 매일 2개씩 뭐든지 포스팅하겠다고 약속한 이상 꾸준히 공부해서 해야한다. 

 

동기와 비동기

우리는 코드를  짤때 위에서 아래로 짜면서 먼저 해야할 연산과 작업을 위에 작성하고 흐름에 맞게 작성하였다. 그러나 다음과 같은 상황에서는 어떨까 ? 

 

console.log("hello ? ")
setTimeout(function(){console.log("i'm fine")},3000);
//setTimeout 함수는 첫번째 인자로 콜백함수를 받고 2번째 인자로 ms(밀리 세컨즈)를 받아 시간이 경과하면 함수를 실행 시킨다.
console.log("and you ? ");

 

우리가 여지것 작성했던 코드를 생각하면 위의 코드는 hello -> 3초뒤 i'm fine-> and you ? 가 작동해야 한다. 그러나 저 코드를 돌려보면 hello - > and you-> i'm fine 순으로 작동한다. 

 

자바스크립트는 함수를 실행하게되면 바로 실행하는 것이 아닌 요청을 하고 다음 코드를 실행한다. 이와 같은 형태를 비동기라고 한다. 

그리고 코드라인의 실행이 끝나면 다음 작업을 하게 되는 것을 동기라고 한다. 

 

만약 자바스크립트가 동기적으로 이루어진다면 어떤 일이 일어날까 ? 

 

페이지를 로딩하며 데이터베이스에서 데이터를 가져온다고 했을 때 페이지는 데이터를 전부 가져오기 전까지 로드되지 않게 된다. 그렇다면 데이터를 로드하기 전까지 사용자는 view도 보지 못하고 다른 기능 또한 사용하지 못할 것이다. 

 

동기적으로 사용해야만 하는 경우 

 

 id를 중복확인 하는 기능이 있다. 이 버튼을 누르고 데이터베이스에 쿼리를 날리고 이 쿼리에 대한 결과가 나와야지만 중복확인을 할 수 있다. 만약 이를 비동기로 짠다면 해당 id를 데이터베이스에 확인요청을 한 뒤 결과가 나오지도 않았는데 결과를 확인해서 null을 반환하게 될것이다.

 

 

콜백으로 동기처리하기

 

setTimeout(()=>{
    console.log("how are you?");
    setTimeout(()=>{
        console.log("i'm fine");
        setTimeout(()=>{
            console.log("and you?")
        },1000)
    },1000)
},1000)

 

 

setTime 함수의 인자로 setTimeout함수를 전달해서 순차적으로 전달 하여 how are you 가 끝나면 1초 뒤 i'm fine이 출력되고 i'm fine이 출력되면 다음 콜백으로 and you가 출력된다. 

 

이렇게 뎁스가 길어지면 콜백지옥에 빠지게 된다. 

 

 

콜백 대체품 프라미스

 

위와 같은 콜백지옥을 해쳐나가기 위해서 async, 프로미스등이 있는데 나는 주로 프라미스를 쓴다.

 

const mysql= require('mysql');

function getId(name,socialnumber){
    return new Promise((resolve, reject)=>{
        mysql.query(`select id from account where id = ${name} and socialnumber = ${socialnumber};`,(error,result)=>{
           if(error){
               reject(new Error(error));
           }
           resolve(result);
        });
    })
}

getId("hokey dokey").then((result)=>{
    console.log(`귀하의 id는 ${result} 입니다.`);
}).catch(()=>{
    console.log("귀하의 id를 찾을 수 없습니다. ")
})

 

프라미스는 객체이며 이 객체의 인자로는 콜백이 들어가고 call back의 파라메터로는 해결했을때 결과를 담는 resolve, 오류가 났을때 오류를 담는 reject가 들어간다. 

 

위의 getId 함수는 mysql 이라는 데이터베이스에서 쿼리를 날리고 그에 대한 결과를 reject와 resolve에 담는다. 

 

이 함수의 호출부에서 .then , .catch를 체인메서드 하듯 작성한다. 

 

그렇다면 이 promise객체의 콜백의 결과로 resolve를 반환하게 되면 .then으로 가게되어 resolve의 값이 .then의 인자에 담기게 된다. 

 

만약 reject를 반환하게 된다면 catch로 가게 된다. 

 

이와 같은 결과로 콜백지옥처럼 오른쪽으로 날카롭게 된 코드를 보지 않고 다음과 같이 깔끔하게 적힌 코드를 사용하게 될 수 있다. 

 

getId("hokey dokey").then((result)=>{
    console.log(`귀하의 id는 ${result} 입니다.`);
}).then((doc)=>{

}).then((data)=>{

}).catch(()=>{
    console.log("귀하의 id를 찾을 수 없습니다. ")
})

 

이 프로미스에 대한 것은 추후 자세히 다룰 예정이다. 

반응형
Comments