velopert님의 모던 자바스크립트 강의자료를 참고하여 작성했습니다.
우선 프로그래밍에서 동기(sync)와 비동기(async)의 정의를 이해할 필요가 있다.
동기 : 이전 작업의 실행이 끝나야 다음 작업 실행을 시작한다.
비동기 : 이전 작업의 실행과 무관하게 다음 작업을 실행한다.
동기와 비동기를 설명할 때 대표적인 예시로 은행과, 카페를 예시로 들곤한다. 은행에서는 사람들에게 번호표를 나눠주고, 이전 사람의 은행 일이 끝날 때 까지는 계속 대기해야 한다. 반면에 카페에서는 주문과 함게 진동벨을 받게 되고 진동벨이 울리기 전에 대기하면서 개인 작업을 할 수 있다.
싱글스레드인 자바스크립트는 기본적으로 동기식이지만, API에 요청을 보낼 때 응답이 올 때까지 마냥 기다리기만 할 수 없기 때문에 비동기 처리가 필요하다.
하지만 비동기 처리를 할 경우, 의도하지 않은 순서로 함수가 실행될 수 있기 때문에 원하는 부분에서 동기 방식으로 변환을 해줘야 한다.
첫번째 방식이 지난번에 살펴본 콜백함수이다. 콜백함수는 함수안에서 또 다른 함수를 호출하는 것인데 여러 함수를 순서대로 호출할 필요가 있을 경우 콜백지옥을 경험하게 되는 문제점이 있다.
숫자 n 을 파라미터로 받아와서 다섯번에 걸쳐 1초마다 1씩 더해서 출력하는 작업을 setTimeout 으로 구현해보자.
function increaseAndPrint(n, callback) {
setTimeout(() => {
const increased = n + 1;
console.log(increased);
if (callback) {
callback(increased);
}
}, 1000);
}
increaseAndPrint(0, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
console.log('끝!');
});
});
});
});
});
비동기를 동기 방식으로 변환하는 두 번째 방법은 Promise객체를 사용하는 것이다. 이번 글에서는 Promise에 대해 알아보자.
Promise는 성공할 수도 있고, 실패할 수 도 있다. 성공할 때는 resolve 함수를 호출하고, 실패할때는 reject 함수를 호출한다.
const myPromise = new Promise((resolve, reject) => {
// 구현..
})
1초 뒤 성공하는 상황을 구현해 보자
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
});
myPromise.then(n => {
console.log(n);
});
resolve 를 호출 할 때 특정 값을 파라미터로 넣어주면, 이 값을 작업이 끝나고 나서 사용 할 수 있다. 작업이 끝나고 나서 또 다른 작업을 해야 할 때에는 Promise 뒤에 .then(...) 을 붙여서 사용하면 된다.
이번에는 1초뒤 실패하는 상황을 만들어보자
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error());
}, 1000);
});
myPromise
.then(n => {
console.log(n);
})
.catch(error => {
console.log(error);
});
실패하는 상황에서는 reject
를 사용하고 .catch
를 통하여 실패했을시 수행할 작업을 설정할 수 있다.
이제 Promise를 만드는 함수를 작성해 보자.
function increaseAndPrint(n) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const value = n + 1;
if (value === 5) {
const error = new Error();
error.name = 'ValueIsFiveError';
reject(error);
return;
console.log(value);
resolve(value);
}, 1000);
});
}
increaseAndPrint(0)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.catch(e => {
console.error(e);
});
Promise 를 사용하면, 비동기 작업의 개수가 많아져도 코드의 깊이가 깊어지지 않게 된다.
프로미스 객체는 생성자를 사용해서 만들 수 있다.
생성자의 인자로 executor라는 함수를 이용한다.
new Promise( /*executor*/ );
executor함수는 resolve와 reject를 인자로 가진다.
(resolve, reject) ⇒ {...}
여기서 resolve와 reject는 각각 함수이다.
new Promise( /*executor*/ (resolve, reject) => {...} );
생성자를 통해 프로미스 객체를 만드는 순간 pending(대기)
상태라고 한다.
new Promise((resolve, reject) => {}); // pending
executor함수 인자중 하나인 resolve함수를 실행하면, fulfilled(이행) 상태가 된다.
new Promise((resolve, reject) => {
//pending
//... 비동기 처리
resolve(); // fulfilled
});
executor함수 인자중 하나인 reject함수를 실행하면, rejected(거부) 상태가 된다.
new Promise((resolve, reject) => {
reject(); // rejected
});
p라는 프로미스 객체는 1초 후에 fulfilled된다.
또한 fulfilled된 시점에 p.then안에 설정한 callback함수가 실행된다.
const p = new Promise((resolve, reject) => {
/*pending*/
setTimeout(() => {
resolve(); /* fulfilled */
}, 1000);
});
p.then(() => {
/* resolve 된 이후에 실행됨*/
/* callback */
console.log('1000ms후에 fulfilled 됩니다.');
});
then을 설정하는 시점을 명확히하고 함수의 실행과 동시에 프로미스 객체를 만들면서 pending이 시작하도록 하기 위해 프로미스 객체를 생성하면서 리턴하는 함수 p를 만들어 p실행과 동시에 then을 설정한다.
function p() {
return new Promise((resolve, reject) => {
/*pending*/
setTimeout(() => {
resolve(); /* fulfilled */
}, 1000);
});
}
//원하는 시점에 프로미스 객체를 생성하고 콜백함수도 호출할 수 있다.
p().then(() => {
console.log('1000ms후에 fulfilled 됩니다.');
});
이번엔 reject상황도 만들어보자. reject는 then이라니라 catch를통해 콜백함수를 처리한다.
function p() {
return new Promise((resolve, reject) => {
/*pending*/
setTimeout(() => {
reject(); /* rejected */
}, 1000);
});
}
//원하는 시점에 프로미스 객체를 생성하고 콜백함수도 호출할 수 있다.
p()
.then(() => {
console.log('1000ms후에 fulfilled 됩니다.');
})
.catch(() => {
console.log('1000ms후에 rejected 됩니다.');
});
excecutor의 resolve함수에 인자를 넣어 실행하면, then의 callback함수의 인자로도 받을 수가 있다.
function p() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello');
}, 1000);
});
}
//원하는 시점에 프로미스 객체를 생성하고 콜백함수도 호출할 수 있다.
p().then(message => {
console.log('1000ms후에 fulfilled 됩니다.', message);
});
마찬가지로 excecutor의 reject함수에 인자를 넣어 실행하면, catch의 callback함수의 인자로도 받을 수가 있다.
function p() {
return new Promise((resolve, reject) => {
/*pending*/
setTimeout(() => {
reject('error');
}, 1000);
});
}
//원하는 시점에 프로미스 객체를 생성하고 콜백함수도 호출할 수 있다.
p()
.then(() => {
console.log('1000ms후에 fulfilled 됩니다.');
})
.catch(reason => {
console.log('1000ms후에 rejected 됩니다.', reason);
});
하지만 일반적으로는 error 문자열이 대신에 객체를만들어서 던진다.
function p() {
return new Promise((resolve, reject) => {
/*pending*/
setTimeout(() => {
reject(new Error('error');
}, 1000);
});
}
//원하는 시점에 프로미스 객체를 생성하고 콜백함수도 호출할 수 있다.
p()
.then(() => {
console.log('1000ms후에 fulfilled 됩니다.');
})
.catch(e => {
console.log('1000ms후에 rejected 됩니다.', e);
});
추가적으로 fulfilled 되거나 rejected된 후에 최종적으로 실행할 것이 있다면, .finally()
를 설정하고, 함수를 인자로 넣는다.
function p() {
return new Promise((resolve, reject) => {
/*pending*/
setTimeout(() => {
reject(new Error('error');
}, 1000);
});
}
//원하는 시점에 프로미스 객체를 생성하고 콜백함수도 호출할 수 있다.
p()
.then(() => {
console.log('1000ms후에 fulfilled 됩니다.');
})
.catch(e => {
console.log('1000ms후에 rejected 됩니다.', e);
})
.finally(() => {
console.log('end');
});
하지만, 이것도 불편한점이 있긴 하다. 에러를 잡을 때 몇번째에서 발생했는지 알아내기도 어렵고 특정 조건에 따라 분기를 나누는 작업도 어렵고, 특정 값을 공유해가면서 작업을 처리하기도 까다로운데 async/await 을 사용하면, 이러한 문제점을 깔끔하게 해결 할 수 있다.
Very educational post! This resource has a wealth of knowledge that can assist any business in launching an effective social media campaign. https://www.gurgaonfairy.com/
I am quite sure I'll learn plenty of new stuff right here!
https://roshnikhanna.home.blog/2024/08/24/8-sexual-massage-types-that-will-create-intense-lust-in-your-partner/ |
https://www.diigo.com/item/note/b4wjx/yjc8?k=2228fa57ed55361b337a3ca0b07c8e47 |
https://roshnikhannaa.wordpress.com/2024/08/24/beat-boredom-and-exhaustion-with-an-erotic-massage/ |
https://www.linkedin.com/pulse/how-gurgaon-companion-can-help-during-business-trip-roshnikhanna-8ixec/ |
https://ameblo.jp/roshanikhanna/entry-12865429925.html |
https://roshanikhanna.amebaownd.com/posts/55122566 |
https://issuu.com/roshnikhanna/docs/escort_agency_in_gurgaon.docx/s/56866193 |
https://pad.fs.lmu.de/s/DsN7tTJLd |
https://roshanikhanna.thezenweb.com/planning-to-hire-gurgaon-escorts-here-is-all-you-need-to-know-67754640 |
https://myheritage.heritage.edu/ICS/Academics/RDG/RDG__502/1920_SU-RDG__502-10/Blog_3.jnz?portlet=Blog_3&screen=View+Post&screenType=next&&Id=7b05ada2-aa53-4698-94ac-11dfb206dfd2 |
https://www.storeboard.com/blogs/personal/meet-gurgaon-escorts-to-find-long-lasting-happiness-and-love/5818745 |
https://roshnikhanna.hashnode.dev/vip-escort-service-in-gurugram-with-hot-girls |
https://devayani.mystrikingly.com/ |
https://devayanikappor.blogspot.com/2024/07/benefits-of-meeting-escorts-regularly.html |
https://justpaste.it/Escort-Service-in-Gurgaon |
https://www.timessquarereporter.com/news/find-your-choice-of-girl-in-gurgaon |
https://bresdel.com/blogs/597422/Get-Luxury-Escorts-Service-in-Gurgaon-at-Affordable-Prices#google_vignette |
https://sites.google.com/view/female-escorts-in-gurugram/ |
https://sites.google.com/view/roshni-khanna/home |
https://roshni-khanna.mystrikingly.com/ |
https://roshni-khanna.blogspot.com/2024/08/full-body-sensual-massage-fbsm.html |
https://ai.ceo/read-blog/171214_erotic-sensual-body-massage-in-gurgaon.html |
https://docs.google.com/forms/d/1KYgpdpLrfkvrGfnt9BtcXXpKuomKceMo7TIOzSGeBYE/viewform?edit_requested=true |
https://roshnikhanna.medium.com/erotic-massage-in-gurgaon-27b79bb73b66
留学生作业代写 http://www.emwchinese.com/store 要想确保高质量,必须在任务理解与沟通、研究与资料收集、写作与结构安排、引用与参考文献以及审校与修改等方面下足功夫。通过充分的沟通、扎实的研究、科学合理的写作结构、正确规范的引用和全面细致的审校,代写者能够确保作业的学术价值和实际意义,满足客户的期望和学术标准,最终获得满意的分数。未来,随着学术要求的不断提升和代写市场的规范化,代写服务还需不断提升自身的专业水平和服务质量,才能在激烈的市场竞争中持续保持领先地位。