callback, promise, async/await

.·2022년 6월 26일
0

blog

목록 보기
49/52

[1] callback

callback은 callback내에서만 코드를 처리해야하고 외부로 반환을 할 수가 없다.

  • callback은 본인 함수 내에서 작업을 해야하므로 콜백지옥이라고 불리는 상황이 발생할 수 있다.

  • 과거에는 await와 같은 방식이 없었으므로 동기적으로 작업을 처리하기 위해서 매개변수에 인자로 함수를 넘겨주었고 만약에 함수를 여러개 거치게 된다면 콜백지옥이 되었던 시절이 있었다.

callback1(function(v1) {
    callback2(function(v2) {
        callback3(function(v3) {
            callback4(function(v4) {
                callback5(function(v5) {

                });
            });
        });
    });
});
const [stateCallback, setStateCallback] = useState([]);

const callbackFunc = async () => {
    const result = await new Promise((resolve, reject) => {
      const aaa = new XMLHttpRequest();
      aaa.open("get", "http://numbersapi.com/random?min=1&max=200");
      aaa.send();
      aaa.addEventListener("load", (res: any) => {
        const num = res.target.response.split(" ")[0];
        console.log(num);
        const bbb = new XMLHttpRequest();
        bbb.open("get", `https://koreanjson.com/posts/${num}`);
        bbb.send();
        bbb.addEventListener("load", (res: any) => {
          const userId = JSON.parse(res.target.response).UserId;
          const ccc = new XMLHttpRequest();
          ccc.open("get", `https://koreanjson.com/posts?userId=${userId}`);
          ccc.send();
          ccc.addEventListener("load", (res) => {
            console.log(res.target); // 지옥이네..
            let test = JSON.parse(res.target.response);
            console.log(test);
            setStateCallback(test);
            // console.log(res.target.response); // 지옥이네..
            // setState1(res);
          });
        });
      });
    });
  };

(1) callback 내부에서 발생한 에러는 잡지 못한다.

위에서 설명하였듯이 콜백함수는 내부에서만 작업을 처리해서 외부에서 인지를 하지 못한다.!!!

// 아래코드는 정상적으로 실행이 되지 않는다.
try {
  setTimeout(() => {
    throw new Error('에러!');
  });
} catch (e) {
  console.error(e);
}

// 콜백함수 내부에서 에러를 잡아서 처리해주어야 작동이된다.
setTimeout(() => {
try {
throw new Error('에러!');
} catch (e) {
console.error(e);
}
});



# [2] promise
> 자바스크립트에서 비동기 처리에 사용되는 객체

*  promise 객체로 저장이 되어 결과값을 저장할 수 있다.
* callback을 사용해서 중첩을 하는 것을 방지할 수 있다.
* 비동기로 어떠한 일을 끝나고 그다음 결과에 따라 처리할 수 있다.
* callback보다는 promise , promise보다는 async/await

## (1) promise 상태
1. pending : 초기상태나 완료전 상태, new Promise()를 호출할 때
2. fulfilled : 성공적으로 완료한 상태, Promise객체.resolve()를 실행할 때
3. rejected : 실패한 상태, Promise객체.reject()나 에러가 발생할 때


## (2) promise 예시

// Promise로 생성자를 만드는 상태를 pending(대기)상태라고 한다.
let myPromise = new Promise((resolve,reject) => {
// resolve함수를 실행하면 fullfilled(이행) 상태
setTimeout( function() {
resolve("성공");
},1000 )

// 혹은

// reject함수를 실행하면 rejected(거부) 상태
setTimeout(() => {
  reject(new Error("에러다")); // reject에서 발생한 에러상태를 .catch()로 보낼 수 있다.
}, 1000);

}

myPromise.
then((result)=> {
console.log("resolve()함수가 실행되었습니다.");
})
.catch(error => {
console.log("reject()함수가 실행되거나 에러가 발생하였습니다.");
})
.finally(()=>{
console.log("무조건 실행이 된다");
});


const [statePromise, setStatePromise] = useState([]);

const promiseFunc = () => {
axios
.get("http://numbersapi.com/random?min=1&max=200")
.then((res) => {
const num = res.data.split(" ")[0];
return axios.get(https://koreanjson.com/posts/${num});
})
.then((res) => {
return axios.get(
https://koreanjson.com/posts?userId=${res.data.UserId}
);
})
.then((res) => {
setStatePromise(res.data);
});
};




## (3) promise 체이닝
> promise를 연속적으로 이어서 사용을 할 수 있다.

.then(FUCNTION)(return new Promise.then(FUCNTION){return new Promise 무한 반복 가능} )

axios.get("")
.then((res) => {
const num = res.data.split("")[0];
return axios.get("");
})
.then((res) => {
const userId = res.data.userId;
return axios.get("");
})
.then((res)=>{
console.log(res);
})


## (4) promise.all

const results = await Promise.all([
uploadFile({ variables: { file: files[0] } }),
uploadFile({ variables: { file: files[1] } }),
uploadFile({ variables: { file: files[2] } }),
]);



# [] promise 생성자 및 메소드(나중에 사용을 하게되면 정리 해볼것...)

* Promise()

* Promise().all()

Promise.all([PROMISE1,PROMISE2,...]).then(FUNCTION)

* Promise().allSettled(iterable)
* Promise.any(iterable)
* Promise.race(iterable)
* Promise.reject(reason)
* Promise.resolve()
* Promise.prototype.catch()
* Promise.prototype.then()
* Promise.prototype.finally()

# [3] Async / Await 
> 자바스크립트에서 비동기로 처리되는 것을 동기로 처리하는 방식이다. 반환값으로 promise객체를 반환해서
.then이나 .catch, .finally 를 사용해서 처리한다.

## (1) async, await
* async는 함수 선언부 앞쪽에 선언되며 동기로 실행을 하겠다는 의미를 줄 수 있습니다. 그리고 async를 선언한 순간 promise객체가 리턴이 됩니다. 

* await는 promise객체를 반환할 때만 사용을 할 수 있다. 즉 promise객체를 반환하지 않는 곳에서 사용을 하여도 await는 작동이 되지 않는다.

* await는 async가 붙어있는 함수 내부에서만 사용이 가능한데 await 키워드가 붙은 비동기처리는 완료가 될 때까지 다음 작업을 실행하지 않고  결과가 나올때까지 기다리고 다음으로 넘어가게 해줍니다. 그러므로 코드가 순서대로 실행이 되는 것을 알 수 있어 코드를 읽기 쉬워집니다. 

let func = async() => {
const result = await func1();
}


위에 callback과 promise 방식에 비해서 깔끔해졌다.

const [stateAsyncAwait, setStateAsyncAwait] = useState([]);

const asyncAwaitFunc = async () => {
const aaa = await axios.get("http://numbersapi.com/random?min=1&max=200");
const num = aaa.data.split(" ")[0];

const bbb = await axios.get(`https://koreanjson.com/posts/${num}`);

const ccc = await axios.get(
  `https://koreanjson.com/posts?userId=${bbb.data.UserId}`
);

console.log(ccc);
setStateAsyncAwait(ccc.data);

};

0개의 댓글