food_pick()
의 호출 주체와 제어권을 가지는 주체,setInterval(food_pick, 500)
의 호출 주체와 제어권을 가지는 주체는 서로 동일한가요?(1)
const menu = ["짜장면", "짬뽕", "탕수육", "군만두"];
const food_pick = function () {
let idx = Math.floor(Math.random() * menu.length);
let selected_menu = menu[idx];
console.log("선택된 메뉴는 :", selected_menu);
console.log("오늘은", selected_menu, "먹는 날!");
};
(2)
const menu = ["짜장면", "짬뽕", "탕수육", "군만두"];
const food_pick = function () {
let idx = Math.floor(Math.random() * menu.length);
let selected_menu = menu[idx];
console.log("선택된 메뉴는 :", selected_menu);
if (selected_menu === "짬뽕") {
console.log("이거지~ 오늘은", selected_menu, "먹는 날!");
clearInterval(menu_recommend);
} else {
console.log("마음에 안 드네요... 다시다시");
}
};
let menu_recommend = setInterval(food_pick, 500);
<aside> 😾 (1)에서의 food_pick( )의 호출 주체와 제어권을 가지는 주체는? ‘사용자’인 것. (2)에서의 setInterval(food_pick, 500)의 호출 주체와 제어권을 가지는 주체는? setInterval에게 있다. 그 이유는? (2)에서 food_pick 함수의 실행을 ‘setInterval’의 첫 인자로 넘겨주었기 때문에, 이때 food_pick 함수의 제어권을 넘겨받았고, (500ms마다) 그 익명함수를 실행하게 될 것이다.
즉, food_pick(콜백 함수)의 제어권을 넘겨받은 setInterval( )은 그 호출 시점을 갖고 자신이 갖고 있기 때문에, 주체와 제어권이 ‘setInterval’로 옮겨진 버전이다.
</aside>
<aside> 😾 다양한 방법들이 있는데, 우선 책에 나와있는 내용으로는 Promise 기법 사용: 비동기 작업의 성공 또는 실패를 처리하기 위해 체이닝 가능한 구조를 제공하고, 콜백 지옥을 피할 수 있게 된다.
물론 단순히 코딩 패턴만으로도 해결할 수 있다. 중첩 선언했던 콜백 익명 함수를 각각의 함수로 구분 하는 방식인데, 이 방식에선 일회성 함수가 존재할 가능성이 있어 많이 선호되진 않는 방식이다.
Async/Await 문법 사용: 비동기 작업을 더 읽기 쉽고 관리하기 쉬운 코드로 만들 수 있다.
코드를 모듈화 & 함수 분리: 코드를 작은 단위로 나누고 각 단위를 함수로 만들어서 모듈화하여 관리한다. 코드 가독성도 높아지고, 콜백 함수 중첩도 줄어든다.
Deno (새로운 Runtime 도구) : Node.js의 문제점을 해결하기 위해 등장. 어떤 문제를? Node.js의 비동기 방식은 크게 콜백 메커니즘으로 되어 있고, 이에 대해서 이제는 업데이트할 예정이 없다. 하지만, Deno는 설계부터 Promise 방식을 지원하고, 모든 비동기 작업은 Promise를 반환한다.
</aside>
<aside> 😾 1. 비동기 작업 중 에러 발생 시, 에러를 콜백 함수의 매개변수로 전달하여 위임 가능. 2. 비동기 작업 순서를 제어 3. 특정 이벤트 발생 시 어떤 동작을 수행하도록 제어 ? 위임함. 4. 동작 지연도 가능: 조건 충족 시 콜백 함수를 호출하여 지연된 동작 수행 시킴 5. 비동기 작업 완료 시 콜백 함수의 매개변수로 전달.
</aside>
<aside> 😾 가장 큰 장점으로 Promise는 체이닝 기법이 가능하기 때문에, 가독성 면에서 우선 뛰어나다. 이것은 코딩을 하는 데에 있어서 작업 플로우가 플렉서블 해지고, 가독성도 좋아진다.
콜백 함수를 중첩하는 것을 지양하고, 체이닝 기법을 사용하기 때문에 콜백 헬을 또한 피할 수도 있다.
에러처리가 쉽게 된다!
비동기 작업의 순차적인 실행과 작업의 흐름 제어가 쉬워진다.
Promise 기반의 Async/Await 기법 사용을 함으로써 비동기 코드를 동기적으로 작성도 가능하다.
Promise 기법은 상태가 존재하는데 이를 통해 상태 추적이 용이하다.
</aside>
<aside> 😾 우선 Promise의 상태에 대해서 설명하자면, 이것은 프로미스의 처리 과정이다. new Promise( )로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖게 되는데, Pending(대기): 비동기 처리 로직이 아직 완료되지 않은 상태 Fulfilled(이행): 비동기 처리가 완료되서 프로미스 결과 값을 반환해준 상태 Rejected(실패): 비동기 처리가 실패하거나 오류가 발생한 상태 로 나눌 수 있는데,
</aside>
new Promise(); 로 메서드를 호출하면 대기(Pending)상태가 된다.
이 때, new Promise(function(resolve, reject) {...}
호출할 때 콜백 함수를 선언할 수 있고, 인자로 resolve, reject가 가능하다.
new Promise(function(resolve, reject){
resolve();
}); // 콜백 함수의 인자 resolve를 아래과 같이 실행하면 이행(fulfilled)상태가 된다.
이렇게 이행 상태가 된다면 then()을 사용하여 처리 결과 값을 반환 받을 수 있는데,
function getData(){
return new Promise(function(resolve, reject){
var data = 100;
resolove(data);
});
}
// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData){
console.log(resolvedData); // 100
});
reject(); 로 호출하면 실패(rejected) 상태가 된다.
그리고, 실패 상태가 되면 실패한 이유(실패 처리의 결과 값)을 catch()문을 통해 받을 수 있다.
getData().then().catch(function(err){
console.log(err); // Error~
});
function gefunction 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 출력
});
Promise의 다른 특징으로 여러 개의 프로미스를 연결하여 사용 가능하다는 점
function getData(){
return new Promise({
//...
});
}
getData()
.then(function(data){
//...
})
.then(function(){
//...
})
. ...