비동기

KoEunseo·2022년 7월 26일
0

javascript

목록 보기
15/32

callback

다른 함수의 전달인자로 넘겨주는 함수

callback in action

  1. 반복실행하는 함수(iterator)
[1,2,3].map((el, i) => return el * el;
  1. 이벤트에 따른 함수(event handler)
document.querySelector('#btn').addEventLister('click', (e) => {
  console.log('btn clicked')
};

tip
함수 자체를 연결해야 하지, 함수를 실행하는 게 아니다.

function handleClick(){console.log('click')};

이 handleClick을
document.querySelector('#btn').onclick = handleClick();
했을때 아무일도 일어나지 않는다.
리턴값이 없기 때문에! undefined를 연결한 셈이 된다.

blocking vs non-blocking

blocking
전화: 하던 일을 멈춰야함. 요청에 대한 결과가 동시에 이루어진다.
non-blocking
문자: 확인 후 나중에 답장. 요청에 대한 결과가 동시에 일어나지 않는다.

비동기 함수 전달 패턴

  1. callback 패턴
let request = 'caffelatte';
orderCoffeeAsync(request, function(response){
  drink(response);
});
  1. 이벤트 등록 패턴
let request = 'caffelatte';
orderCoffeeAsync(request).onready = function(response){
  drink(response);
}

비동기의 쓰임

  • DOM Element
    -click, keydown
    -페이지 로딩
  • 타이머
    -타이머API, 애니메이션API
  • 서버에 자원 요청 및 응답
    -fetch API, AJAX

about event loop

비동기 순서를 제어하고 싶은 경우: 콜백함수를 사용한다.

! 콜백지옥

const printString = (string, callback) => {
  setTimeout(
  () => {
	console.log(string);
	callback()
	},
    Math.floor(Math.random() * 100) + 1;
  )
}

const printAll = () => {
  pringString("A", ()=> {
    pringString("B", ()=> {
      printString("C", ()=> {})
    })
  })
} //ABC 순서대로 나온다.

Promise

const pr = new Promise((resolve, reject) => {
  setTimeout(()=>{
    resolve('OK');
  }, 3000)
});
//state: pending(대기), result: undefined
//3초후
//state: fulfilled(이행), result: 'OK'
const pr = new Promise((resolve, reject) => {
  setTimeout(()=>{
    resject(new Error('error..'));
  }, 3000)
});
//state: pending(대기), result: undefined
//3초후
//state: rejected(거부), result: error
pr.then(
  function(result){} //이행됐을때
  function(err){} //거부됐을때
);
//catch() //reject됐을때 쓸 수 있음.
pr.then(
  function(result){}
).catch(
  function(err){}
).finally(
  function(){
    console.log('끗!')
  }
)

new로 Promise를 생성한다.
콜백함수 : resolve(성공), reject(실패)를 받는다.

  1. new Promise
    state: pending(대기)
    result: undefined
  1. resolve(value)
    state: fulfilled(이행)
    result: value
  1. reject(error)
    state: rejected(거부)
    result: error
  1. .catch()
    reject일때 catch를 쓸 수 있다.
  1. .finally()
    이행됐을때든 거부됐을때든 작업이 끝날때 항상 실행시킨다.

Promise Chaining

콜백지옥에서 탈출하기 위해 사용한다!
new Promise()로 함수를 생성하고
함수를 실행할 때 .then()으로 순차적으로 연결한다.
맨 마지막에 .catch()를 통해 에러를 잡을 수 있다.

console.log('start');
func1()
  .then((res) => func2(res))
  .then((res) => func3(res))
  .then((res) => console.log(res))
  .catch(console.log)
  .finally(()=>{
    console.log('the end');
  }) //start -> func1 -> func2 -> func3 -> the end

Promise.all([func1(), func2()..])

각각 완료시점이 다른 작업들을 한꺼번에 시작하고 모두 이행되면 값을 사용할 수 있게 된다.
reject가 될 경우에는 error가 뜬다.
모든 작업이 수행되거나 수행되지 않아야 할 때 사용.

Promise.all([func1(), func2(), func3()]).then((res)=> {
  console.log(res);
})

async await

Promise Chain보다 가독성이 좋다!

함수 앞에 async 키워드를 주면 항상 Promise를 반환한다.
그렇기 때문에 함수를 호출할 때 .then을 사용할 수 있다.

async function getName(){
  return Promise.resolve('Tom');
}

getName().then((name)=> {console.log(name);});

> await은 async 내부에서만 사용할 수 있다.
```javascript
function getName(name) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(name);
    }, 1000);
  });
}
async function showName() {
  const result = await getName('Mike');
  console.log(result);
}
console.log('start');
showName(); //시작 찍히고 1초후 Mike 반환
//getName에서 res를 받을때까지 기다렸다가 반환을 하는 것
async() => {}
console.log('start');
async function order() {
  try{ //rejected되면 err가 나오기 때문에 try-catch문으로 감싸준다.
  	const result1 = await func1();
  	const result2 = await func2(result1);
  	const result3 = await func3(result2);
  	console.log(result3);
  } catch(e){
    console.log(e);
  }
  console.log('the end');
}

order(); //start -> func1 -> func2 -> func3 -> the end

오늘 페어분께서 디스코드 사용법을 알려주셨다 놀랍게도 굉장히 실용적임 굳굳 앞으로는 줌말고 디스코드로 해야징

profile
주니어 플러터 개발자의 고군분투기

0개의 댓글