일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 내장고차함수
- variable#function
- https://dasima.xyz/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%A0%9C%EA%B3%B1-math-pow-%EA%B3%84%EC%82%B0/
- removeCookie
- Beesbeesbees
- User Flow
- ㄷㅌ
- 자바스크립트#JS#slice#splice
- 자바스크립트
- cmarket
- UI
- JS#3일차달리자#초반인데#시간금방~
- 자바스크립트#조건문#문자열
- redux상태유지
- https://lo-victoria.com/introduction-to-redux-toolkit-for-beginners
- children vs childrenNodes
- slice/splice/split
- UX
- 노드교과서
- toString#String
- @redux-toolkit
- https://www.daleseo.com/js-array-slice-splice/
- CSS
- 자바스크립트#JS#var#let#const#undefined#null
- 헷갈린다~
- js
- react
- https://developer-talk.tistory.com/299
- dom
- for~in/for~of
- Today
- Total
Daily Front_Minhhk
[JS] 비동기[callBack, Promise, async-await] 본문
학습 목표
- 어떤 경우에 중첩된 콜백(callback)이 발생하는지 이해할 수 있다.
- 중첩된 콜백(callback)의 단점, Promise의 장점을 이해할 수 있다.
- async/await 키워드에 대해 이해하고, 작동 원리를 이해할 수 있다.
blocking vs non-blocking
- 요청에 대한 결과가 동시에 일어난다 (synchronous) → 동기
- 요청에 대한 결과가 동시에 일어나지 않는다 (asynchronous) → 비동기
asynchronous 예제
function waitAsync(callback, ms) {
setTimeout(callback, ms); // 특정 시간 이후에 callback 함수가 실행되게끔 하는 브라우저 내장 기능입니다
}
function drink(person, coffee) {
console.log(person + '는 ' + coffee + '를 마십니다');
}
function orderCoffeeSync(coffee) {
console.log(coffee + '가 접수되었습니다');
waitSync(2000);
return coffee;
}
let customers = [{
name: 'Steve',
request: '카페라떼'
}, {
name: 'John',
request: '아메리카노'
}];
function orderCoffeeAsync(menu, callback) {
console.log(menu + '가 접수되었습니다');
waitAsync(function() {
callback(menu);
}, 2000);
}
// call asynchronously
customers.forEach(function(customer) {
orderCoffeeAsync(customer.request, function(coffee) {
drink(customer.name, coffee);
});
});
callback
const printString = (string, callback) => {
setTimeout(function () {
console.log(string);
callback();
}, Math.floor(Math.random() * 100) + 1);
};
const printAll = () => {
printString('A', () => {
printString('B', () => {
printString('C', () => {});
});
});
};
printAll();
// A
// B
// C
Promise
- 프로미스는 자바스크립트 비동기 처리에 사용되는 객체
- 여기서 자바스크립트의 비동기 처리란
- ‘특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성’
function getData() {
return new Promise(function(resolve, reject) {
$.get('url 주소/products/1', function(response) {
if (response) {
resolve(response);
}
reject(new Error("Request is failed"));
});
});
}
// 위 $.get() 호출 결과에 따라 'response' 또는 'Error' 출력
getData()
.then(function(data) {
console.log(data); // response 값 출력
})
.catch(function(err) {
console.error(err); // Error 출력
});
Pending(대기)
먼저 아래와 같이 new Promise() 메서드를 호출하면 대기(Pending) 상태가 됩니다.
new Promise();
new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject입니다.
new Promise(function(resolve, reject) {
// ...});
Fulfilled(이행)
여기서 콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행(Fulfilled) 상태가 됩니다.
new Promise(function(resolve, reject) {
resolve();
});
그리고 이행 상태가 되면 아래와 같이 then()을 이용하여 처리 결과 값을 받을 수 있습니다.
function getData() {
return new Promise(function(resolve, reject) {
var data = 100;
resolve(data);
});
}
// resolve()의 결과 값 data를 resolvedData로 받음getData().then(function(resolvedData) {
console.log(resolvedData);// 100});
※ 프로미스의 '이행' 상태를 좀 다르게 표현해보면 '완료' 입니다.
Rejected(실패)
new Promise()로 프로미스 객체를 생성하면 콜백 함수 인자로 resolve와 reject를 사용할 수 있다고 했습니다. 여기서 reject를 아래와 같이 호출하면 실패(Rejected) 상태가 됩니다.
new Promise(function(resolve, reject) {
reject();
});
그리고, 실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있습니다.
function getData() {
return new Promise(function(resolve, reject) {
reject(new Error("Request is failed"));
});
}
// reject()의 결과 값 Error를 err에 받음getData().then().catch(function(err) {
console.log(err);// Error: Request is failed});
.catch( () ⇒ {} )
더 많은 예외 처리 상황을 위해 프로미스의 끝에 가급적 catch() ㄱㄱ
// catch()로 오류를 감지하는 코드
function getData() {
return new Promise(function(resolve, reject) {
resolve('hi');
});
}
getData().then(function(result) {
console.log(result); // hi
throw new Error("Error in then()");
}).catch(function(err) {
console.log('then error : ', err); // then error : Error: Error in then()
});
Promise Chaining
function getData() {
return new Promise({
// ...
});
}
// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
.then(function(data) {
// ...
})
.then(function() {
// ...
})
.then(function() {
// ...
});
ex
new Promise(function(resolve, reject){
setTimeout(function() {
resolve(1);
}, 2000);
})
.then(function(result) {
console.log(result); // 1
return result + 10;
})
.then(function(result) {
console.log(result); // 11
return result + 20;
})
.then(function(result) {
console.log(result); // 31
});
Promise.all 사용하기
Promise.all은 배열 내 모든 값의 이행(또는 첫 번째 거부)을 기다립니다.
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("foo");
}, 100);
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});
async await
async & await 기본 문법
- async & await을 사용하면 동기적으로 코드를 짜는 것처럼 비동기 처리를 할 수 있다.
- function 앞에 async를 붙이면 코드 블럭안이 Promise로 자동 변환
async function 함수명() {
await 비동기_처리_메서드_명();
}
// 함수 선언식
async function funcDeclarations() {
await 작성하고자 하는 코드
...
}
// 함수 표현식
const funcExpression = async function () {
await 작성하고자 하는 코드
...
}
// 화살표 함수
const ArrowFunc = async () => {
await 작성하고자 하는 코드
...
}
복잡한 Promise 코드를 간결하게 작성할 수 있게 되었습니다.
함수 앞에 async 키워드를 사용하고 async 함수 내에서 await 키워드를 사용하면 됩니다.
이렇게 작성된 코드는 await 키워드가 작성된 코드가 동작하고 나서야 다음 순서의 코드가 동작하게 됩니다.
const printString = (string) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
console.log(string);
}, Math.floor(Math.random() * 100) + 1);
});
};
const printAll = async () => {
await printString('A');
await printString('B');
await printString('C');
};
printAll();
console.log(
`Async/Await을 통해 Promise를 간결한 코드로 작성할 수 있게 되었습니다.`
);
function gotoCodestates() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('1. go to codestates')}, 100)
})
}
function sitAndCode() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('2. sit and code')}, 100)
})
}
function eatLunch() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('3. eat lunch')}, 100)
})
}
function goToBed() {
return new Promise((resolve, reject) => {
setTimeout(() => { resolve('4. go to bed')}, 100)
})
}
// async await
const result = async() => {
const one = await gotoCodestates();
console.log(one)
const two = await sitAndCode()
console.log(two)
const three = await eatLunch()
console.log(three)
const four = await goToBed()
console.log(four)
}
result()
// 1. go to codestates
// 2. sit and code
// 3. eat lunch
// 4. go to bed
async & await 예외 처리
async & await에서 예외를 처리하는 방법은 바로 try catch입니다.
프로미스에서 에러 처리를 위해 .catch()를 사용했던 것처럼
async에서는 catch {} 를 사용하시면 됩니다.
조금 전 코드에 바로 try catch 문법을 적용해보겠습니다.
async function logTodoTitle() {
try {
var user = await fetchUser();
if (user.id === 1) {
var todo = await fetchTodo();
console.log(todo.title);// delectus aut autem}
} catch (error) {
console.log(error);
}
}
위의 코드를 실행하다가 발생한 네트워크 통신 오류뿐만 아니라 간단한 타입 오류 등의 일반적인 오류까지도 catch로 잡아낼 수 있습니다.
발견된 에러는 error 객체에 담기기 때문에 에러의 유형에 맞게 에러 코드를 처리해주시면 됩니다.
'Code개발일지' 카테고리의 다른 글
[JS] fs모듈 (part-2) (0) | 2022.11.25 |
---|---|
[JS] 타이머API[setTimeout,setInterval() ] / (node.js)-fs.readFile(path[, options], callback) (0) | 2022.11.24 |
[JS] {Beesbeesbees}, super, extends, class, constructor( ),get-set (0) | 2022.11.21 |
[JS] 프로토타입, 체인 (0) | 2022.11.18 |
[OOP] 객체지향 프로그래밍 (0) | 2022.11.18 |