본문 바로가기
Web/js

JavaScript(2)

by ormgm 2020. 2. 6.

Promise

: 자바스크립트 비동기 처리에 사용되는 객체로 생성자를 통해서 프로미스 객체를 만들수 있고 생성자의 인자로 executor 함수를 사용한다. executor함수는 resolve와 reject함수를 인자로 가진다. 생성자를 통해서 객체를 만드는 순간을 대기(pending) 상태라고 한다. resolve함수를 실행하면 이행(fulfilled) 상태가 된다. reject함수를 실행하면, 거부(rejected) 상태가 된다.

* 비동기 처리 : 특정 코드의 실행이 완료될 떄까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성

 

new Promise((resolve,reject)=>{ // executor

    resolve(); // fulfilled

    reject(); // rejected

})

 

1번 방법

const p = new Promise((resolve,reject) =>{

    setTimeout(() =>{

        resolve();

    },1000);//1초후 실행

})

p.then(()=>{ //p 라는 프로미스 객체가 fulfilled되는 시점에 p.then 안에 설정한 callback함수가 실행됨

    console.log('1000ms 후에 fulfilled 됩니다.');

}); 

 

2번 방법

 then을 설정하는 시점을 정확히하고, 함수의 실행과 동시에 프로미스 객체를 만들면서 pending이 시작하도록 하기 휘애 프로미스 객체를 생성하면서 return하는 함수를 만들어 함수 실행과 동시에 then을 설정합니다.

 

function p (){

    return new Promise((resolve,reject) =>{

        setTimeout(() =>{

            resolve();

        }, 1000);//1초후 실행

    });

}

 

p().then(() => {

    console.log('1000ms 후에 fulfilled 됩니다.');

})

 

reject()가 실행되면 catch가 실행되고 resolve()가 실행되면 then이 실행됨

function p (){

    return new Promise((resolve,reject) =>{

        setTimeout(() =>{

            reject();

        }, 1000);//1초후 실행

    });

}

 

p().then(() => {

    console.log('1000ms 후에 fulfilled 됩니다.');

}).catch(()=>{

    console.log('1000ms 후에 rejected 됩니다.');

})

 

resolve함수에 인자를 넣어 실행하면 then의 callback함수의 인자로 받을 수 있음

function p (){

    return new Promise((resolve,reject) =>{

        setTimeout(() =>{

            resolve('hello');

        }, 1000);//1초후 실행

    });

}

 

p()

.then(message => {

    console.log('1000ms 후에 fulfilled 됩니다.', message);

})

.catch(()=>{

    console.log('1000ms 후에 rejected 됩니다.');

})

 

reject함수에 인자를 넣어 실행하면 catch의 callback함수의 인자로 받을 수 있음

function p (){

    return new Promise((resolve,reject) =>{

        setTimeout(() =>{

            reject('error');

        }, 1000);//1초후 실행

    });

}

 

p()

.then(message => {

    console.log('1000ms 후에 fulfilled 됩니다.', message);

})

.catch((reason)=>{

    console.log('1000ms 후에 rejected 됩니다.', reason);

})

 

표준 내장 객체인 Error의 생성자를 이용하여 Error 객체를 만들어  catch의 callback함수의 인자로 받는게 일반적

function p (){

    return new Promise((resolve,reject) =>{

        setTimeout(() =>{

            reject(new Error('bad'));

        }, 1000);//1초후 실행

    });

}

 

p()

.then(message => {

    console.log('1000ms 후에 fulfilled 됩니다.', message);

})

.catch((error)=>{

    console.log('1000ms 후에 rejected 됩니다.', error);

})

 

fulfilled 되거나 rejected된 후에 최종적으로 실행할 것이 있다면 .finally()를 설정

function p (){

    return new Promise((resolve,reject) =>{

        setTimeout(() =>{

            reject(new Error('bad'));

        }, 1000);//1초후 실행

    });

}

 

p()

.then(message => {

    console.log('1000ms 후에 fulfilled 됩니다.', message);

})

.catch((error)=>{

    console.log('1000ms 후에 rejected 됩니다.', error);

})

.finally(() => {

    console.log('end');

})

 

callback을 활용한 비동기 작업

비동기 작업 시 callback 함수를 인자로 넣어 로직이 끝나면 callback함수를 호출함

함수가 아래로 진행되지 않고, callback함수 안으로 진행됨

function c(callback){

    setTimeout(()=>{

        callback();

    },1000);

}

 

c(()=>{

    console.log('1000ms 후에[ callback함수가 실행됩니다.');

})

c(()=>// callbackhell

    c(() =>{

        c(()=>{

            console.log('1000ms 후에[ callback함수가 실행됩니다.');

        });

    });

});

 

Promise를 이용한 비동기 작업

then함수에서 다시 프로미스 객체를 리턴하는 방법을 통해 체이닝하면, 비동기 작업을 순차적으로 아래로 표현할 수 있음

function p(){

    return new Promise((resolve,reject)=>{

        setTimeout(()=>{

            resolve();

        },1000);

    });

}

 

p()

.then(()=>{

    return p();

})

.then(() => p()) // return p()에 속하는 then

.then(p) // then(() => p())에 속하는 then

.then(()=>{ //then(p)에 속하는 then

    console.log('4000ms 후에 fulfilled됩니다.');

})

 

Promise.resolve(value);

Promise라는 전역객체의 resolve함수를 실행하면서 Promise생성하는 것으로 value에는 Promise 객체 또는 일반 값이 들어간다.

value가 프로미스 객체인지 아닌지 알 수 없는 경우, 연결된 then 메서드를 실행시킴

value가 프로미스 객체면 resolve된 then 메서드를 실행시킴

value가 프로미스 객체가 아니면 value를 인자로 보내면서 then메서드를 실행시킴

Promise.resolve(new Promise((resolve,reject) => {

    setTimeout(() =>{

        resolve('foo');

    },1000);

})

).then((data) => {

    console.log('프로미스 객체인 경우, resolve 된 결과를 받아 then이 실행 됩니다.', data,);

});

 

Promise.resolve('bar').then(data => {

    console.log('then 메서드가 없는 경우, fulfilled 됩니다.', data);

})

 

 

Promise.reject(value);

cath로 연결된 rejected 상태로 변경됨

별로 사용되지는 않음

Promise.reject(new Error('reason'))

    .then(error =>{})

    .catch(error =>{

    console.log(error);

})

 

Promise.all([프로미스 객체들]);

프로미스 객체 여러개를 생성하여, 베열로 만들어 인자를 넣고 Promise.all을 실행하면

배열의 모든 프로미스 객체들의 fufilled 되었을 때, then의 함수가 실행됨

then의 함수의 인자로 프로미스 객체들의 resolve 인자값을 배열로 돌려줌

function p(ms){

    return new Promise((resolve,reject) => {

        setTimeout(()=>{

            resolve(ms);

        },ms);

    })

}

 

Promise.all([p(1000), p(2000), p(3000)]).then((messages) => {

    console.log('모두 fulfilled된 이후에 실행됩니다.', messages);

})

 

 

Promise.race([프로미스 객체들])

프로미스 객체 여러개를 생성하여, 베열로 만들어 인자를 넣고 Promise.race을 실행하면

배열의 모든 프로미스 객체들 중 가장 먼저 fufilled 된 것으로 then의 함수가 실행됨

then의 함수의 인자로 가장 먼저 fulfilled된 프로미스 객체의 resolve 인자값을 돌려줌

function p(ms){

    return new Promise((resolve,reject) => {

        setTimeout(()=>{

            resolve(ms);

        },ms);

    })

}

 

Promise.race([p(1000), p(2000), p(3000)]).then((message) => {

    console.log('가장 빠른 하나가 fulfilled된 이후에 실행됩니다.', message);

 

 

Async - Await

Promise를 기반으로 하고, await를 사용하는 경우 항상 async 함수 안에서 사용해야 함

로직이 아래로 흘러가게 표현한다는 점이 장점

function p(ms){

    return new Promise((resolve,reject=>{

        setTimeout(()=>{

            resolve(ms);

        }, ms);

    })

}

 

(async function main(){

    const ms = await p(1000);

    console.log(`${ms} ms 후에 실행된다.`);

})();

 

try catch

Promise 객체가 rejected된 경우의 처리를 위해 사용

function p(ms){

    return new Promise((resolve,reject=>{

        setTimeout(()=>{

            reject(new Error('resone'));

        }, ms);

    })

}

 

(async function main(){

    try{

    const ms = await p(1000);

    }catch(error){

        console.log(error);

    }

})();

 

async function

function p(ms){

    return new Promise((resolve,reject) =>{

        setTimeout(()=>{

            resolve(ms);

            //reject(new Error('reason'));

        }, ms);

    })

}

 

async function asyncP(){

    const ms = await p(1000);

// 이렇게 할 경우 에러는 전파되기 때문에 catch문으로 가게됨. 그렇게 하고싶지 않으면 여기서도 try-catch를 사용하면 됨

    return 'Mark: ' + ms;

}

 

(async function main(){

    try{

        const name = await asyncP(1000);

        console.log(name);

    }catch(error){

        console.log(error);

    }finally{

        console.log('end');

    }

})();



Promise와 async await 비교

function p(ms){

    return new Promise((resolve,reject) =>{

        setTimeout(()=>{

            resolve(ms);

            //reject(new Error('reason'));

        }, ms);

    })

}

 

//Promise

p(1000)

    .then(() =>  p(1000))

    .then(() => p(1000))

    .then(() =>{

        console.log('3000 ms 후에 실행');

    })

 

//async await 

(async function main(){

    await p(1000);

    await p(1000);

    await p(1000);

    console.log('3000 ms 후에 실행');

})

 

//Promise.all

(async function main(){

    const results = await Promise.all([p(1000), p(2000), p(3000)]);

    console.log(results);

})();

 

//Promise.race

(async function main(){

    const result = await Promise.race([p(1000), p(2000), p(3000)]);

    console.log(result);

})();




'Web > js' 카테고리의 다른 글

인사이드 자바스크립트  (0) 2020.03.10
JavaScript(1)  (0) 2020.02.04

댓글