JS3

KwangYong·2021년 12월 23일
0

JavaScript

목록 보기
3/3

👨🏻‍🏫 JSON

👨🏻‍🏫 비동기 처리의 시작 콜백 이해하기

source : 드림코딩 js기초11

동기, 비동기, 콜백함수

JavaScript is synchronous
Execute the code block by order after hoisting.
synchronous: hoisting된 이후부터 코드가 우리가 작성한 순서에 맞춰서 하나하나 실행된다.
※ hoisting: var, function declaration 이런 선언들이 자동적으로 제일 위로 올라가는 것.

asynchronous: 비동기적으로 언제 코드가 실행될지 예측할 수 없는 것.
콜백함수: 우리가 전달해준 함수를 나중에 불러줘

console.log('1');
setTimeout(() => console.log(2), 1000);
console.log('3'); 

setTimeout에는 타임 핸들러라는 콜백함수를 전달해주고, timeout시간제한 지정하는 인자들이 있다. timeout만큼 지나면 콜백함수가 실행됨.
이런 브라우저api는 무조건 브라우저한테 먼저 요청을 보냄. 보낸 후 응답을 기다리지 않고 다음 코드 실행함.
브라우저에서 1초가 지난 후에 알려주면 그때서야 콜백함수를 실행함.
여기서 지정한 함수는 바로 실행되는 것이 아니라 setTimeout이라는 함수안에 하나의 파라미터 인자로 우리가 지정한 함수를 전달해줌
그래서 당장 실행하진 않고 니가 나중에 1초가 지난 다음에 내 함수를 콜 해줘 -> 콜백

콜백이 비동기일때만 사용하는 것이 아니라 콜백도 두가지 경우로 나눠진다.

  • Synchronous callback: 즉각적으로 동기적으로 실행
function printImmediately(print) { //함수 선언은 hoisting으로 맨 위로 올라간다.
    print();
}
printImmediately(()=>console.log('hello'));
  • Asynchronous callback: 나중에 언제 실행될지 예측불가
function printWithDelay(print, timeout){
    setTimeout(print, timeout);
}
printWithDelay(()=>console.log('async callback'), 2000);

콜백 지옥

//Callback Hell example
class UserStorage {
    loginUser (id, password, onSuccess, onError){
        setTimeout(() => {
            if(
                (id === 'ellie' && password === 'dream') ||
                (id === 'coder' && password === 'academy')
            ) {
                onSuccess(id);
                //onSuccess 콜백함수를 id를 매개변수로 하면서 호출한다.
            } else
            onError(new Error('not found'));
        }, 2000);
    }

    getRoles(user, onSuccess, onError){
        setTimeout(() => {
            if(user === 'ellie'){
                onSuccess({mname: 'ellie', role: 'admin'});
                //object를 생성해서 매개변수로 전달
            } else {
                onError(new Error('no access'));
            }
        }, 1000);
    }
}

const userStorage = new UserStorage();
//입력받기
const id = prompt('enter your id');
const password = prompt('enter your password');

userStorage.loginUser(
    id, password, (user) => {
        userStorage.getRoles(
            user,
            (userWithRole)=>{
                alert(
                    `Hello ${userWithRole.mname}, you have a ${userWithRole.role} role`
                );
            },
            (error)=> {console.log(error);}
        );
    },
    (error) => {console.log(error)}
);

👨🏻‍🏫 PROMISE

source : 드림코딩 js기초12

Promise is a JavaScript Object for asynchronous operation.
promise는 js안에 있는 Object.
비동기적인 것을 수행할 때 콜백함수 대신에 유용하게 쓰는 object.

두 가지 특징
1. state
2. Producer vs Consumer

🍃 state: pending -> fulfilled or rejected
프로미스가 만들어져서 우리가 지정한 operation이 수행중일 때는 pending
이 operation을 성공적으로 다 끝내게 되면 fulfilled가 되고 파일을 찾을 수 없거나 네트워크 문제 발생시 rejected

🍃 우리가 원하는 기능을 수행해서 해당하는 데이터를 만들어내는 producer
우리가 원하는 데이터를 소비하는 consumer로 나뉨.

1. Producer

new 키워드로 Promise object를 생성. 생성자에서 executer콜백함수를 인자로 받는데
executer는 다시 resolve, reject 콜백함수를 인자로 받음.
promise object를 생성한 순간, 바로 executer함수가 실행됨.
when new Promise is created, the executor runs automatically.

const promise = new Promise((resolve, reject) => {
    //doing some heavy work (network, read files) 시간이 걸리는 일들은 비동기 처리할것.
    console.log('doing something...');
    setTimeout(() => {
        // resolve('kwang');
         //실패했을 때 사용되는 reject함수는 보통 error라는 object를 전달.
        reject(new Error('no network'));
    }, 2000);
});

2. Consumers: then, catch, finally

성공(resolve): then -> promise가 잘 수행된다면 값을 받아와서 콜백함수 수행.
여기서 value는 promise가 정상 수행되서 resolve콜백함수에서 전달된 값.
실패(reject): catch 실행
then이 (값 or promise)를 리턴하기 때문에 그 후에 리턴된 promise에 catch를 등록함.
finally: 성공이든 실패든 항상 실행

promise.then((value) => {
    console.log(value);
})
.catch(error => {
    console.log(error);
})
.finally(() => {
    console.log('finally');
});

3. Promise chaining

then은 값을 전달해도 되고 또 다른 비동기인 promise를 전달할 수 있음.

const fetchNumber = new Promise((resolve, reject) => {
    setTimeout(() => resolve(1), 1000);
});

fetchNumber
    .then(num => num*2)
    .then(num => num*3)
    .then(num => {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve(num-1), 1000);
        });
    })
    .then(num => console.log(num));

4. Error Handling

const getHen = () =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve('🐓'), 1000);
    });
const getEgg = hen =>
    new Promise((resolve, reject) => {
        setTimeout(() => reject(new Error(`error! ${hen} => 🥚`)), 1000);
    });
const cook = egg =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve(`${egg} => 🍳`), 1000);
    });
 getHen()
     .then(hen => getEgg(hen))
     .then(egg => cook(egg))
     .then(meal => console.log(meal));

받아오는 value를 다른 함수의 인자로써 호출하는 경우에는 생략해서 코드 작성가능.
에러가 발생했을 때 then 바로 뒤에다가 catch를 둠으로써 다른 값을 리턴하면
그 리턴값으로 대체되면서 Promise chaining이 유지된다.

getHen()
.then(getEgg)
.catch(error => {
    return '🥯';
})
.then(cook)
.then(console.log)
.catch(console.log);

collback-to-promise.js

🍃 콜백지옥을 promise로 벗어나자

//Callback Hell example
class UserStorage {
    loginUser (id, password){
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if(
                    (id === 'ellie' && password === 'dream') ||
                    (id === 'coder' && password === 'academy')
                ) {
                    resolve(id);
                } else{
                    reject(new Error('not found'));
                }
            }, 2000);
        });
    }

    getRoles(user){
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if(user === 'ellie'){
                    resolve({mname: 'ellie', role: 'admin'});
                    //object를 생성해서 매개변수로 전달
                } else {
                    reject(new Error('no access'));
                }
            }, 1000);
        });
    }
}

const userStorage = new UserStorage();
//입력받기
const id = prompt('enter your id');
const password = prompt('enter your password');

// 인자가 똑같으면 생략 가능
userStorage.loginUser(id, password)
.then(userStorage.getRoles)
.then(userWithRole => {
    alert(`hello ${userWithRole.mname}, you have a ${userWithRole.role} role`);
})
.catch(console.log);

👨🏻‍🏫 Await

profile
바른 자세로 코딩합니다 👦🏻💻

0개의 댓글