7월달은 약속이나 일정이 많아서 추가적인 공부를 할 시간이 좀 부족하다.. 8월달은 그 시간을 확보하고 바로 포트폴리오도 준비하면서 공부할 것이다. 일단은 피그마도 연습해보고, 포트폴리오 틀 잡아서 내용 채운 다음에 사이트로도 제작해 보고자 한다. 내일 자취방 이사도 있어서 시간이 많을지는 모르겠지만 그래도 해봐야지 허허

 

비동기 처리(동시에 처리하는 것)

seTimeout(코드,delay) 를 사용하여 처리할 수 있다.

특정 코드의 연산이 끝날때까지 코드의 실행을 멈추지 않고 다음코드를 먼저 실행하는 자바스크립트의 특성이다.

 

pay가 먼저 실행되기 때문에 전역변수안에 값이 들어가지 않는다.

 

콜백 함수

자바스크립트는 함수를 인자로 받고 다른 함수를 통해 반환될 수 있는데, 인자로 대입되는 함수를 콜백함수라고 한다.

즉, 다른 함수가 실행된 후에 실해되는 함수이다.

함수를 선언할때는 파라미터로 함수를 받아서 쓸 수 있다.

이를 사용하는 이유는 비동기 방식으로 작성된 함수를 동기 처리하기 위해 사용된다.

콜백 지옥

비동기 프로그래밍 시 발생하는 문제이다. 콜백함수가 반복될수록 단계가 깊어지기 때문에 코드의 가독성이 떨어지고, 코드 수정 난이도가 엄청나게 커질수가 있다.

이러한 문제를 해결하기 위해 나온것이 promise 객체이다


promise 객체

비동기 함수를 동기 처리하기 위해 만들어진 객체

성공과 실패를 분리하여 반환

비동기 작업이 완료된 이후에 다음작업을 연결시켜 진행할 수 있는 기능을 가짐

 

• Pending(대기) : Promise를 수행 중인 상태

• Fulfilled(이행) : Promise가 Resolve 된 상태 (성공)

• Rejected(거부) : Promise가 지켜지지 못한 상태. Reject 된 상태 (실패)

• Settled : fulfilled 혹은 rejected로 결론이 난 상태

 

위와 같은 상태를 가진다.

 

Promise는 두가지 콜백 함수를 가진다.

resolve(value) : 작업이 성공한 경우 그 결과를 value와 함께 호출 > then 메소드 활용

reject(error) : 에러 발생 시 에러 객체를 나타내는 error와 함께 호출 > catch 메소드 활용

finally > 성공 실패와 상관없이 호출

then, catch를 사용하면 결과값만 가져온다.

 

Promise 체이닝

then으로 연결하기 때문에 콜백 지옥에 빠지지 않을 수 있고, 순차적으로 작업을 할 수 있다.

예외 처리도 마지막에 catch로 지정할 수 있어서 편하다.

//체이닝을 사용 안 한 경우
//(4+3)*2-1

function add(n1, n2, callback){
    setTimeout(function(){
        let result = n1 + n2;
        callback(result);
    },1000);
}

function mul(n, callback){
    setTimeout(function(){
        let result = n *2;
        callback(result);
    },700);
}

function sub(n, callback){
    setTimeout(function(){
        let result = n -1;
        callback(result);
    },500);
}

//add
add(4, 3, function(x){
    console.log("1 : ", x)
    mul(x, function(y){
        console.log("2 :", y);
        sub(y, function(z){
            console.log("3 :", z);
        })
    })
})

 

//Promise 체이닝
//장점 : tnen 메서드를 연속해서 쓸 수 있다. > 순차적인 작업이 가능하다.
//예외처리도 마지막에 catch로 지정하면 되기 때문에 간편하다.

function add(n1, n2){
    return new Promise(function(resolve,reject){
        setTimeout(function(result) {
            result = n1 + n2;
            resolve(result);
            // callback(result);
        },1000);
    });

}

function mul(n){
    return new Promise(function(resolve,reject){
        setTimeout(function(result) {
            result = n *2;
            resolve(result);
            // callback(result);
        },700);        
    });

}

function sub(n){
    return new Promise(function(resolve,reject){
        setTimeout(function(result) {
            result = n -1;
            // resolve(result);
            // callback(result);
            reject(new Error("에러처리"));// 에러 객체 만들어서 에러 처리하기
            // PS C:\Users\82103\Documents\KDT-8-Web\230729_비동기처리> node 230729_promise.js
            // 1 :  7
            // 2 :  14
            // Error: 에러처리
            //     at Timeout._onTimeout (C:\Users\82103\Documents\KDT-8-Web\230729_비동기처리\230729_promise.js:140:20)
            //     at listOnTimeout (node:internal/timers:569:17)
            //     at process.processTimers (node:internal/timers:512:7)
        },500);        
    });

}

//add
add(4, 3).then(function(result){
    console.log("1 : ", result);
    //then을 연속적으로 쓸려면 여기서 값을 반환해줘야한다.
    return mul(result);    
}).then(function(result){
    console.log("2 : ", result);
    //then을 연속적으로 쓸려면 여기서 값을 반환해줘야한다.
    return sub(result);    
}).then(function(result){
    console.log("3 : ", result);    
}).catch(function(err){
    console.log(err);
});

두 코드를 비교해보면 체이닝을 한 것이 가독성도 높고 예외 처리 다루기가 훨씬 쉽다. (사실 체이닝 안할때의 예외 처리는 솔직히 잘 모른다..)


async/await

프로미스 기반 코드를 좀 더 쓰기 쉽고, 읽기 쉽게 하기 위해 등장했다.

• async

• 함수 앞에 붙여 Promise를 반환한다.

• 프로미스가 아닌 값을 반환해도 프로미스로 감싸서 반환한다.

• await

• ‘기다리다’ 라는 뜻을 가진 영단어

• 프로미스 앞에 붙여 프로미스가 다 처리될 때까지 기다리는 역할을 하며 결과는 그 후에 반환한다.

 

//async와 await은 항상 같이 사용한다.

let product;
let price;
exec();

function goMart(){
    console.log("마트에 와서 어떤 음료를 마실까");
}

function pickDrink() {
    return new Promise(function(resolve, reject){
        setTimeout(function(){
            console.log("고민 끝!!");
            product = "사이다";
            price = 2000;
            let mymoney = 2000;
            if(price <= mymoney){
                resolve();
            }else{
                reject("돈이 부족해요");
            }
        }, 3000);
    })
}

function pay(){
    console.log(`상품명 : ${product}, 가격 : ${price}`);
}

이 상태에서 아래와 같이 사용한다.

async function exec() {
    goMart(); // 먼저 실행 1번
    await pickDrink(); // 2번
    pay();// 3번 pay가 pickDrink의 실행이 끝날때까지 기다려야 함으로 pickDrink 앞에 await을 붙여준다.

}

 

+ Recent posts