javaScript/etc

나홀로 js // 프로미스 -1

부엉이사장 2022. 6. 30. 14:41

일단 아는것들은 생략하고 쓰도록 하겠다.

 

 

#1 프로미스를 리턴하는 함수.

함수안에 들어있는 프로미스는 함수가 실행되면 바로 실행이 되어버린다.

 

먼저 코드

let promise = new Promise((resolve, reject)=>{
    resolve('하잉');
}).then((data)=>{return data+'하이잉'})
.then((data)=>{return data+'gkdkdk'})
.catch(err=>console.log)

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

function hello(){
}

첫번쨰는 일반적인 프로미스.. 코드가 더럽더라도 양해바란다. 바로 쓴거라서..

그리고 두번째는 함수가 프로미스를 리턴한다.

세번째는 그냥 일반적인 함수다. 함수내용에 리턴없이 아무거나 쳐도 된다.

 

- 그럼 먼저 첫번째 프로미스의 타입을 살펴보자.

console.log(typeof(promise))

결과값은 object가 나온다. 프로미스는 객체이기 때문이다.

 

- 딜레이 함수

결과값은 오브젝트가 나온다. 함수가 프로미스를 리턴하기 때문이다.

 

- hello 일반함수

결과는 undefined가 나온다. 아무것도 리턴해주지 않았기 때문이다.

 

여기서 특이한점은

async function hello(){
}

헬로우 일반함수를 async를 붙여서 이 함수의 타입을 출력해주면

object가 나온다. 어떤 함수에도 async를 붙이면 프로미스를 반환하기때문에

타입값은 객체가 된다는것이다.

 

사실 기초강의를 배울때는 그닥 중요하겠어? 내가 원하는 순서대로 진행만 되면 되지 

이렇게 안일하게 생각했는데, 막상 이런 기본 개념들이 없어서 코드가 순서대로 안되는것같아서

다시 기초부터 쌓는중이다 ㅠㅠ

 

 

# 딜레이함수 만들기 

위에 개념을 잡지 못해서 실수했던것.

맨처음 내가 만들었던 delay 함수는 이렇다

function delay(ms){
    let promise = new Promise((resolve, reject)=>{
        setTimeout(()=>{resolve(), ms})
    })
}

delay(3000).then(() => console.log('3초후 실행'))

함수 delay안에 promise가 담겨있다. 그런데 이 함수는 return을 안하니

then이 붙을수가 없다. 프로미스는 코드실행시 바로 

 

 

 

중요한것 

.then() 괄호안에는 ()=>{}식으로 함수가 들어가야한다

예를들어 .then(console.log('hello'))이런식으로 들어가면

이 콘솔은 프라미스가 만들어지는 즉시 실행이 되어버린다. 프로미스안에 지연함수가 있더라도

쌩까고 걍 실행되버림..

 

async function f1() {
    let promise = new Promise((resolve, reject) => {
      setTimeout(() => resolve(), 5000);
    })
    .then(console.log('이거 5초후에 실행되야하는거 아냐?'))
    //   .then((data)=>console.log(data))
      .catch((err) => console.error);
    await promise;
    let result = "바보1"; // 프라미스가 이행될 때까지 기다림 (*)
    console.log(result); // "완료!"
  }

이런식으로 만들면.. 바로 저 5초 텍스트 콘솔창에나오고

5초후에 result가 출력이된다.

 

 

## 원하는 값을 return하는 async함수

그럼 시간이 걸리는 함수들이 서로 데이터를 주고받으며 원하는 순서대로 실행되게 하려면 어떻게해야할까? 

이거 존나 중요하다. 이거때문에 고민했던거임.

async함수는 자동적으로 프로미스를 리턴하기때문에 .then으로 처리를 해야만하는줄 알았다..

return을 붙이더라도 이 함수를 밖에서 쓰려면 

await을 붙여야하는데 코드상단에선 await을 붙일수가 없기 때문이다.

이걸 해결하는 방법이다.

 

 

1.

const childFunc = async () => {
  await new Promise((r) => setTimeout(r, 1000));
  return "hello";
};

아기함수 코드다. 이 함수는 1초 딜레이되는 프로미스를 기다린 후, 'hello'라는 스트링을 리턴한다.

 

console.log(childFunc())

근데 이 함수 리턴값인 헬로우를 얻으려고 출력해보면 프로미스가 튀어나와버린다 ㅠㅠ

그럼 이 hello스트링을 얻으려면 어떻게해야하나?

 

그래서 다른 async함수로 감싸주었따.

async function f1(){
    return await childFunc()
}

console.log(f1())

근데 역시 f1역시 비동기함수라 프로미스를 자동적으로 리턴한다 시발 ㅋㅋㅋㅋ

async함수의 리턴값을 쓰려면 어떻게 해야할까?

 

아기함수의 리턴값을 다른함수에서 쓰고 싶다면

const parentFunc = async () => {
  try {
    console.log(await childFunc())
  } catch {
    return "error!";
  }
};

엄빠함수를 만들었다. 난 아기함수의 리턴값 hello를 엄빠함수에서 쓰고싶다.

근데 만약 console.log(chindFunc())으로 쓰면 콘솔에 프로미스가 바로찍힌다.

1초대기따위도 없어져버리게 된다.

 

그래서 await을 붙인다.

 

로직은

childFunc는 async함수라서 프로미스이다. 따라서 여기에 await을 붙일 수 있는데

붙이게되면 이 아기함수가 다 끝날때까지 기다린후 리턴하는진짜 값 hello를 쓸 수 있는것이다.

 

 

와 이거 이해하는데 너무 어려웠다..

단순한건데.. ㅠㅠ