비동기
드림코딩 11~13
https://www.youtube.com/watch?v=aoQSOZfz3vQ&t=31s
https://github.com/dream-ellie/learn-javascript/blob/master/notes/async/async.js
동기적 (synchronous)
→ 요청에 대한 결과가 동시에 일어난다
서버로 접속하는 컴퓨터가 어떤 요청을 하면 서버가 요청을 받고 처리하는 동안 사용자는 응답을 기다리게 됩니다.
하나의 작업이 끝날 때까지, 이어지는 작업을 막는 blocking이 발생하게 되는 것입니다.
비동기적 (asynchronous)
→ 요청에 대한 결과가 동시에 일어나지 않는다
서버로 접속하는 컴퓨터가 어떤 요청을 하면 서버가 요청을 받고 처리하는 동안 사용자는 응답을 기다리는 것이 아니라,
계속해서 일을 하다가 서버의 응답을 받고 무언가를 할 수 있습니다. (non-blocking)
1) 동기 : 전체 load 시간 = 기능 1 + 2 + 3 + 4에 걸리는 시간
2)비동기 : 전체 load 시간 = 기능 4에 걸리는 시간 → 시간이 짧게 걸림, 효율 좋음
Node.js는 비동기적(asynchronous)으로 작동하는 런타임입니다.
JavaScript의 비동기적 실행(Asynchronous execution)이라는 개념은 웹 개발에서 특히 유용합니다.
특히 아래 작업은 비동기적으로 작동되어야 효율적입니다.백그라운드 실행, 로딩 창 등의 작업인터넷에서 서버로 요청을 보내고, 응답을 기다리는 작업큰 용량의 파일을 로딩하는 작업
callback function (콜백 함수)
다른 함수의 전달인자(arguement)로 넘겨주는 함수.
parameter를 넘겨받는 함수(A)는 callback 함수(B)를 필요에 따라
1) synchronous callback (즉각 실행)
(1) callback 받아서 바로 실행하는 함수
function B() {
consol.log('call at the back')
}
function A (callback){
callback;
}
A(B); // 즉시 실행!
(2) 아무런 인자를 받지 않는 함수
func(() => console.log('let the hope shine in'));
2) asynchronous callback(나중에 실행)
function printWithDelay(print,timeout){
setTimeout(print,timeout);
}
// print와 timeout이라는 두 parmeter에 들어온 arguement를 setTimeout에 전달해준다.
// printWithDelay는 wrapping function이다.
printWithDelay(()=>console.log('async callback'),3000); //3초뒤에 출력
callback in action : 반복 실행하는 함수 (iterator)
[1,2,3].map(function(el,idx){
return el * el ;
})
callback in action : 이벤트에 따른 함수 (eventhandler)
document.quarySelector('#btn').addEventListener('click',function(e){
console.log('button clicked');
});
이 때 헷갈리기 쉬운 것은
function handleClick(){
console.log('button clicked');
};
document.quarySelector('#btn').onclick = handleClick; //👌
document.quarySelector('#btn').onclick = function(){handleClick();}//👌
document.quarySelector('#btn').onclick = handleClick.bind();//👌
document.quarySelector('#btn').onclick = handleClick() ; //안됨 ❌
//함수 실행을 연결하는 것이 아닌 함수 자체를 연결해야 한다.
※ bind()
bind()를 사용하면 this가 어떤 instance를 가리킬 것인지 선택할 수 있습니다.
myWan = {
name: 'jw',
getName: function() {
return this.name;
}
}
myWan.getName(); // "jw"
// myWan의 getName이란 key의 value인 function을 바로 호출할 수 있다.
getTheName = myWan.getName
getTheName();
// getTheName 함수에는 this에는 name이라는 key가 존재하지 않는데?!
// 그럼 bind()를 사용하면 됨.
getTheName = getTheName.bind(myWan);
getTheName(); // 출력결과 'jw'
//bind()로 this 키워드가 myWan을 참조하도록 했다.

비동기 호출(asynchronous call)
비동기 JavaScript
setTimeout()
setTimeout(함수, 밀리초) 콜백 함수를 밀리초 뒤에 리턴하게 된다.
console.log('1');
setTimeout(function(){
console.log('2');
},1000);
console.log('3');
//1
//3
//2 (1초 뒤에 찍힘)
// 비동기적인 js 실행방법.
Callback
어떤 경우에 중첩된 콜백(callback)이 발생하는지 이해할 수 있다.
Promise
비동기를 간편하게 처리할 수 있도록 도와주는 object.
정해진 장시간의 기능을 수행하고 나서
정상적으로 기능이 수행되었다면 성공의 메시지와 함께 처리된 결과값을 보여줌
수행하다가 예상치 못한 문제가 발생한다면 에러를 전달해줍니다.
※ 요점
state(상태)
pending(보류중) → fulfilled (충족) or rejected(거부됨)
process가 heavy한 operation을 수행하고 있는 중인지, 수행이 끝나고 성공했는지에 대한 상태입니다.
// 1. Producer
// new Promise가 만들어질 때는 전달한 콜백함수가 바로! 자동적으로! 실행된다. 유념할 것.
// 'P'romise 라고 표기해줘야함, resolve는 성공했을 떄, rejects는 실패했을 때 불러오는 함수
const promise = new Promise(resolve,reject) =>{
console.log('doing somthing...');
setTimeout(function()=>{
resolve('ellie'); // 성공하는 경우
// reject(new Error('no network')) // 실패하는 경우.
//어떤 에러가 발생했는지 이유를 잘 명시해서 작성해야 함
},2000);
}
// 2. Consumers : then, catch, finally
promise.then(value =>{ //promise가 성공적으로 수행되었다면
console.log(value); //원하는 콜백함수의 내용. value === 'elile'
})
// then이란 promise가 정상적으로 잘 수행되어서,
//최종적으로 value라는 콜백함수를 통해서 value라는 parameter로 전달되어 들어오는 것.
.catch(error=>{ // promise를 수행하는 과정에서 문제가 발생했다면
console.log(error);
})
// chaining.then을 호출했을 때 promise가 return되고, return된 promise에 catch를 등록하는 것.
.finally()=>{console.log('finally')};
//성공 실패 여부와 상관없이 무조건 마지막에 호출되어짐.
// 3. Promise chaining
const fetchNumber = new Promise((resolve,reject)=>{
setTimeout() => resolve(1),1000
})
fetchNumber
.then(num => num * 2)
.then(num => num * 3)
.then(num => return new Promise((resolve,reject) => {
setTimeout(() => resolve(num -1),1000)
})
});
.then(num => console.log(num)); // 5가 1초 뒤에 찍힘
// 4. Error Handling
const getHen = () =>
new Promise((resolve, reject) => {
setTimeout(() => resolve('🐓'), 1000);
});
const getEgg = hen =>
new Promise((resolve, reject) => {
setTimeout(() => reject(new Error(`error! ${hen} => 🥚`)), 1000);
});
const cook = egg =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(`${egg} => 🍳`), 1000);
});
getHen()
.then(getEgg)
.catch(error => '🍅')//오류를 잡아냄. 만약 계란을 받아올 때 문제가 생긴다면 '🍅'로 대체
// 계란을 받아오는 것에 문제가 생겨도 전체적인 Promise 과정에 펑크나지 않도록 하는 것
.then(cook)
.then(console.log)
.catch(console.log);
// getHen()
//.then(hen => getEgg(hen))
//.then(egg => cook(egg))
//.then(meal => console.log(meal)) 위처럼 생략 가능함
producer(promise object) & consumer
우리가 원하는 데이터를 제공하는 사람 & 데이터를 쓰는, 필요로 하는 사람
async & await
promise를 좀 더 간결하고 동기적으로 실행되는 것처럼 보이게 만들어주는 API.
syntactic sugar.
// 1. async
async function fetchUser() {
// do network reqeust in 10 secs....
return 'ellie';
// return new Promise ((resolve,reject) {return 'ellie';})
// 이렇게 하면 resolve나 reject를 호출하지 않았기 때문에 pending,보류상태로 머물게됨
// 그래서 promise안에는 꼭 resolve나 reject를 호출해야 함.
// return new Promise ((resolve,reject) {resolce('ellie');}) // resolve 호출.
}
const user = fetchUser();
user.then(console.log);
console.log(user);
// 2. await ✨
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getApple() {
await delay(2000); // await은 async가 붙은 함수내에서만 사용 가능.
//throw 'error'; // 에러 발생의 경우 에러 사유 적어줌.
return '🍎'; // 2초가 지나면 '🍎'를 전달함.
}
async function getBanana() {
await delay(1000);
return '🍌';
}
//async function pickFruits() {
// try{const apple = await getApple();
// const banana = await getBanana();}
// catch(){ 에러 상황 처리}
// return `${apple} + ${banana}`;
//}
// 에러 발생의 경우 에러 처리하는 방법.
//function pickFruits(){
//return getApple().then(apple => {
// banana => `${apple} + ${banana}`; })
//}
//pikcFuits().then(console.log); 랑 같은데 promise도 중첩을 계속하면 또 콜백지옥에 빠짐
async function pickFruits() {
const applePromise = getApple();
const bananaPromise = getBanana();
const apple = await applePromise;
const banana = await bananaPromise;
return `${apple} + ${banana}`;
} // 이 부분 잘 이해안감.❤️🔥
//async로 비동기화한 함수가 promise로 만든거랑 같으니까 그 함수를 내부에서 호출해주면 적는순간 바로 실행되서
// 34번째줄 try안처럼 적어주면 원래 1+1 2초걸리는데 여기서는 동시에 1초 걸려서 총 1초 걸림.
pickFruits().then(console.log);
// 3. useful APIs ✨
function pickAllFruits() {
return Promise.all([getApple(), getBanana()]).then(fruits =>
fruits.join(' + ')
);
}
pickAllFruits().then(console.log);
function pickOnlyOne() {
return Promise.race([getApple(), getBanana()]);
}
pickOnlyOne().then(console.log);