Web/JavaScripts

[JavaScripts] 비동기 사용방법

usingsystem 2023. 4. 17. 17:56
728x90

SetTimeout

function taskA() {
  setTimeout(() => {
    console.log("A Task Eed");
  }, 2000);
}

taskA();
console.log("코드 작업 끝");

SetTimeout을 사용하면 비동기적으로 행위를 처리할 수 있다. 

앞에 인자 값엔 행위를 넣어주고 뒤에는 앞에 전달한 행위가 시작 기다림이다.

 

SetTimeout은 실행이 되면 Call Stack에 쌓였다가 WebApis로 넘어가서 정해진 시간 동안 기다리다 시작하게 된다. 그렇기 때문에 아래코드가 먼저 실행될 수 있다.

 

콜백함수와 SetTimeout

function taskA(a, b, cb) {
  setTimeout(() => {
    const res = a + b;
    cb(res);
  }, 3000);
}

function taskB(a, cb) {
  setTimeout(() => {
    const res = a * 2;
    cb(res);
  }, 1000);
}

function taskC(a, cb) {
  setTimeout(() => {
    const res = a * -1;
    cb(res);
  }, 2000);
}

taskA(3, 4, (res) => {
  console.log("A Task Result : ", res);
});

taskB(7, (res) => {
  console.log("B Task Result : ", res);
});

taskC(10, (res) => {
  console.log("C Task Result : ", res);
});

console.log("코드 작업 끝");

 

콜백 지옥 

taskA(4, 5, (a_res) => {
  console.log("A RESULT : ", a_res);
  taskB(a_res, (b_res) => {
    console.log("B RESULT : ", b_res);
    taskC(b_res, (c_res) => {
      console.log("C RESULT : ", c_res);
    });
  });
});

Resolve와 Reject

function isPositive(number, resolve, reject) {
  setTimeout(() => {
    if (typeof number === "number") {
      // 성공 -> resolbe
      resolve(number >= 0 ? "양수" : "음수");
    } else {
      // 실패 -> reject
      reject("주어진 값이 숫자형 값이 아닙니다.");
    }
  }, 2000);
}

isPositive(
  10,
  (res) => {
    console.log("성공적수행", res);
  },
  (err) => {
    console.log("실패함", err);
  }
);

Promise

function isPositiveP(number) {
  const executor = (resolve, reject) => {
    setTimeout(() => {
      if (typeof number === "number") {
        // 성공 -> resolbe
        console.log(number);
        resolve(number >= 0 ? "양수" : "음수");
      } else {
        // 실패 -> reject
        reject("주어진 값이 숫자형 값이 아닙니다.");
      }
    }, 2000);
  };
  const asyncTask = new Promise(executor);
  return asyncTask;
}
const res = isPositiveP(10);

res
  .then((res) => {
    console.log("성공적수행", res);
  })
  .catch((err) => {
    console.log("실패함", err);
  });

promise를 리턴하는 function은 모두 then을 사용할 수 있다.

Then 체이닝

function taskA(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000);
  });
}

function taskB(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}

function taskC(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const ref = a * -1;
      resolve(ref);
    }, 2000);
  });
}

//Promise then체이닝
taskA(5, 1)
  .then((a_res) => {
    console.log("A RESULT : ", a_res);
    return taskB(a_res);
  })
  .then((b_res) => {
    console.log("task B : ", b_res);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log("task C : ", c_res);
  }); 
  
  //Promise 콜백지옥
  // taskA(5, 1).then((a_res) => {
//   console.log("A RESULT : ", a_res);
//   taskB(a_res).then((b_res) => {
//     console.log("task B : ", b_res);
//     taskC(b_res).then((c_res) => {
//       console.log("task C : ", c_res);
//     });
//   });
// });

//일방적인 콜백지옥
// taskA(3, 4, (a_res) => {
//   console.log("task A : ", a_res);

//   taskB(a_res, (b_res) => {
//     console.log("task B : ", b_res);

//     taskC(b_res, (c_res) => {
//       console.log("task C : ", c_res);
//     });
//   });
// });

콜백지옥을 사용하지 않기위해 promise를 사용하여 then 체 이닝으로 만든다.

 

async & await

 

async function helloAsync() {
  return "helloAsync";
}

async를 function 앞에 쓰게되면 promise를 반환하게 된다. promise를 좀 더 쉽게 사용할 수 있다.

 

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

async function helloAsync() {
  await delay(3000);
  return "helloAsync";
}

async function main() {
  const res = await helloAsync();
  console.log(res);
}

main();

await을 사용하면 동기적으로 만들어준다.

728x90