자바스크립트 JS 공부 #7 비동기처리, promise, then, async/await

사공 오·2022년 4월 14일
0

JS 공부

목록 보기
7/11
post-thumbnail

동기적 - 차례대로 실행됨 (그거하는 동안 다른거 못함)
비동기적 - 흐름이 멈추지 않기 때문에 동시에 여러작업 처리
기다리는 과정에서 다른 함수 호출가능

비동기 처리

function work(callback) {
    setTimeout(() => { //비동기처리가능
        const start = Date.now(); //현재 시간을 숫자 형태로 가져오는 내장 함수
        for (let i = 0; i < 1000000000; i++) {} //1,000,000,000 번 루프돌고
        const end = Date.now();
        console.log(end - start + 'ms'); // 얼마나 걸렸는지 알려줌
        callback(end - start)
    }, 0); //실제론 4ms 이후에 수행됨 (브라우저가 설정한 최소값)
}

console.log('작업 시작!'); //1번째 실행
work((ms) => {
    console.log('작업이 끝났어요!');
    console.log(ms + 'ms가 걸렸다고 해요.');
}); //3번 실행 
// 콜백함수 -  이 펑션이 끝나고 실행됐으면 하는거 설정할때 사용
//함수 타입의 값을 파라미터로 넘겨줘서, 파라미터로 받은 함수를 특정 작업이 끝나고 호출을 해주는 것을 의미

console.log('다음 작업'); //2번째

setTimeout(() => { },0); --> 비동기처리가능
콜백함수 - 이 펑션이 끝나고 실행됐으면 하는거 설정할때 사용

비동기 처리를 해야하는 경우

  • Ajax Web API 요청: 만약 서버쪽에서 데이터를 받아야 할 때는, 요청을 하고 서버에서 응답을 할 때 까지 대기를 해야 되기 때문에
  • 파일 읽기: 주로 서버 쪽에서 파일을 읽어야 하는 상황에
  • 암호화/복호화: 바로 처리가 되지 않고, 시간이 어느정도 걸리는 경우가 있기 때문에
    작업 예약



promise

function increaseAndPrint(n, callback) {
    setTimeout(() => {
        const increased = n + 1;
        console.log(increased);
        if (callback) {
            callback(increased);
        }
    }, 1000);
}

increaseAndPrint(0, n => {
    increaseAndPrint(n, n => {
        increaseAndPrint(n, n => {
            increaseAndPrint(n, n => {
                increaseAndPrint(n, n => {
                    console.log('끝!');
                });
            });
        });
    });
});

n을 다섯번에 걸쳐 1초마다 1씩 더해서 출력하는 작업을 setTimeout 으로 구현 - 콜백지옥

const myPromise = new Promise((resolve, reject) => { //성공 할 때에는 resolve를 호출, 실패할 때에는 reject를 호출
    setTimeout(() => {
        resolve('n'); //n 반환
    }, 1000); //1초뒤에 성공
});

myPromise.then(n => { //then - 프로미스 끝나고 실행할거 설정
    console.log(n);
});
//성공할때 

const myyPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error()); //에러 발샹
    }, 1000);
});

myyPromise.then(n => {
        console.log(n);
    })
    .catch(error => { //실패했을때 수행할 함수
        console.log(error);
    });

//실패할때 에러날떄 

프로미스 사용법


function increaseAndPrint(n) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const value = n + 1;
            if (value === 5) { //5되면 에러만듦
                const error = new Error();
                error.name = 'ValueIsFiveError'; //에러 이름지정가능
                reject(error);
                return;
            }
            console.log(value);
            resolve(value); //1더한 값 반환
        }, 1000); //1초뒤에 실행 
    });
}

Promise 를 만드는 함수


increaseAndPrint(0)
    .then(n => { // 이형식이랑 밑이랑 같음 파라미터랑  리턴하는 함수에서 쓰는 인자가 같기떄문에
        return increaseAndPrint(n);
    })
    .then(increaseAndPrint)
    .then(increaseAndPrint)
    .then(increaseAndPrint)
    .then(increaseAndPrint) //5는 안되게 설정하였기 때문에 에러잡힘
    .catch(e => {
        console.error(e);
    });

then은 이렇게 뒤에 붙여서 여러개 연달아 사용가능


async/await - ES8

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function process() { //펑션 선언항때 앞에 async 붙이고
    console.log('안녕하세요!');
    await sleep(1000); // 프로미스앞에 await 1초쉬고 실행
    console.log('반갑습니다!');
}


process().then(() => {
    console.log('작업이 끝났어요!');
});

async function makeError() {
    await sleep(1000);
    const error = new Error();
    throw error; //throw로 에러발생
}

async function process() {
    try { //에러를 잡아낼 때에는 try/catch 문
        await makeError();
    } catch (e) {
        console.error(e);
    }
}

async 함수에서 에러를 발생 시킬때


const getDog = async () => {
    await sleep(1000);
    return '멍멍이';
};

const getRabbit = async () => {
    await sleep(500);
    return '토끼';
};
const getTurtle = async () => {
    await sleep(3000);
    return '거북이';
};

async function process() {
    /*
    이렇게하면  순서대로 진행됨 동기적 실행
    const dog = await getDog(); //앞에 어웨잇 붙여야함
    console.log(dog);
    const rabbit = await getRabbit();
    console.log(rabbit);
    const turtle = await getTurtle();
    console.log(turtle);
    */

    const [dog, rabbit, turtle] = await Promise.all([ //프로미스 올을 사용해서 동시에 작업을 시작 - 이중에 하나라도 오류나면 에러발생
        getDog(),
        getRabbit(),
        getTurtle()
    ]);
    console.log(dog);
    console.log(rabbit);
    console.log(turtle);

}

process();

Promise.race

가장 빨리 끝난것 하나만의 결과값을 가져옴 - 가장빨리끝난게 에러나야 에러나고 아니면 에러안남 (쓸일 많지는 않음)

async function process() {
    const first = await Promise.race([
        getDog(),
        getRabbit(),
        getTurtle()
    ]);
    console.log(first);
}

process();

0개의 댓글