동기와 비동기
동기 - 순차적인 흐름을 가짐
- 하나의 작업이 실행되는 동안 다른 작업들은 대기 상태
비동기 - 비순차적
- 작업 순서를 기다리지 않고 바로 다음 작업 수행
비동기 처리
처리 완료되지 않아도 다음 코드 실행
데이터를 받아 온 후 코드 실행되는 경우 비동기 처리
자바스크립트는 싱글 스레드로 동작
웹이 발전하면서 단순 콜백만으로는 모든 상황 통제가 어려움
=> 비동기 처리 코드들을 동일한 api 형태로 사용할 수 있게 추가된 것이 Promise
비동기 처리 종류
Promise, await/async, fetch
Promise -> then, catch
await/async -> try-catch
fetch -> 접근하려는 url과 매개변수로 네트워크 요청 보냄
setTimeout()
for문 하는 동안 다른 일도 하고 싶다면(비동기) -> setTimeout 함수 사용
함수를 의도적으로 지연한 뒤 실행하고 싶을 때 사용하는 함수
큐
선입선출 방식, 먼저 들어온게 먼저 나감
프로미스 Promise
JS의 오브젝트로 비동기적을 수행할 때 콜백함수 대신 사용
사용하는 이유?
=> 비동기 처리 코드를 표준 api 형태로 사용 가능하도록 추가
=> 비동기 코드를 promise 객체화 가능
=> 메소드 체인 형태로 callback depth 균일화
=> 프로미스로 생성된 비동기 인스턴스는 한 번만 실행 됨
=> 에러 분기를 catch로 전달
=> 비동기 처리에서 발생하던 안좋은 패턴을 개선할 수 있도록 도와주는 새로운 비동기 표준
const promise = new Promise((resolve, reject) => {
})
.then(result => result)
.catch(err => err)
.finally(result => result)
resolce : 일이 성공적으로 끝난 경우
reject : 에러 발생 시 에러 객체를 나타내는 에러와 함께 호출
프로미스 상태
- pending(대기) - resolve(해결) - fulfilled(이행)
- pending(대기) - reject(거부) - rejected(실패)
프로미스는 성공 / 실패만 해야함
resolve, reject 중 하나를 반드시 호출
let p = new Promise(function(resolve, reject){
resolve('hello world');
}).then(메시지 => {
alert(메시지)
return 메시지.split(' ')[0]
}).then(메시지 => {
alert(메시지)
return 메시지.split(' ')[0]
})
let p = new Promise(function(resolve, reject){
reject('hello world');
})
console.log(p);
let p = new Promise(function(resolve, reject){
reject('hello world')
}).catch(메시지 => {
alert('catch 실행!!')
return 'catch!!'
})
console.log(p)
then
프로미스 정상적 수행되어 resolve라는 콜백 함수 통해서 전달
프로미스에 then 호출하면 then은 결국 똑같은 프로미스를 리턴 -> catch를 다시 호출 가능
=> 프로미스 체이닝
catch
에러가 발생한 경우만 다루고 싶은 경우에 사용
finally
성공이든 실패이든 상관없이 무조건 마지막에 호출되는 메서드
어떤 기능을 마지막으로 수행하고 싶을 때 사용
promise
.then(value => {
console.log(value);
})
.catch(error => {
console.log(error);
})
.finally(() => {
console.log('-제주맛집');
});
error
let p = new Promise(function(resolve, reject){
resolve('hello world')
}).then(메시지 => {
alert(메시지)
return 메시지.split(' ')[0]
}).then(메시지 => {
alert(메시지)
throw Error('Error 발생! 경고경고!')
return 메시지[0]
}).then(메시지 => {
alert(메시지)
return 메시지
}).catch(메시지 => {
console.log(메시지)
alert('catch 실행!!')
})
console.log(p)
let p = new Promise(function(resolve, reject){
setTimeout(()=>resolve('끝났다!'),3000)
})
console.log('hello world')
console.log(p)
프로미스 체이닝
let p = new Promise(function(resolve, reject){
setTimeout(()=> resolve(1),10000)
})
console.log('hello world');
let p2 = p.then(function(result){
console.log(result);
return result * 2;
})
console.log('hello world2');
let p3 = p2.then(function(result){
console.log(result);
return result * 2;
})
console.log('hello world3');
async function (async/await)
async function
프로미스의 문제점
=> 특정 조건에 따른 분기 나누기 어려움
=> 어디에서 에러 발생하였는지 파악 어려움
=> 가독성이 떨어져 .then 지옥 발생 가능
==> 해결 방법 async/await
프로미스 기반으로 동작
.then 없이 비동기를 동기처럼 동작 가능하도록 구현
async function 함수이름() {
return 결과 값;
}
.then()
let a = async function() {
return 'hi';
}
a().then(console.log);
async function f() {
return 'hello world';
}
console.log('!');
f()
.then(메시지 => {
alert(메시지);
return 메시지.split(' ')[0];
})
.then(메시지 => {
alert(메시지);
return 메시지.split(' ')[0];
})
console.log('!!');
awync & await
비동기 처리가 되어야 하는 부분 앞에 await 키워드 넣기
await 키워드는 async 안에서만 사용 가능하며
프로미스 앞에서 사용해야 함
async function f() {
await 비동기처리메서드이름();
}
const one = () => Promise.resolve('one')
async function f() {
console.log('in function')
const res = await one()
console.log(res)
}
console.log('before function')
f();
console.log('after function')
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(()=> resolve('ok!'), 1000)
});
let result = await promise;
alert(result);
}
f()
let result = promise;
console.log(result);
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 10000)
});
let result = promise;
console.log(result);
alert(result);
return 'hello'
}
f();
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
alert("완료")
resolve("완료!")
}, 1000)
});
let result = promise;
console.log(result);
alert(result);
return 'hello'
}
f();
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
alert("완료")
resolve("완료!")
}, 1000)
});
let result = await promise;
console.log(result);
return 'hello'
}
f();