자바스크립트는 동기적으로 작동됩니다. 즉, 각 코드 블록이 이전 블록 이후에 실행 됩니다.
const data = fetch(`api-url`);
console.log("완료");
cnosole.log(data);
fetch가 비동기로 동작합니다. fetch가 완료되지 않아 console.log(data)에 undefined가 나오게 됩니다. 이러한 일들을 비동기 처리해준다고 말하며 동기적으로 작동시키도록 코드를 바꿔보겠습니다.
비동기 코드를 동기식으로 작동하게 하는 방법 중 가장 기본적인 방법이 callback을 이용하는 방법입니다.
하지만 이를 난발할 경우 콜백 지옥이라는 말이 나오는 상황이 발생하게 됩니다.
function doSomething(callback) {
setTimeout(function() {
console.log("First thing done");
callback();
}, 1000);
}
function doSomethingElse(callback) {
setTimeout(function() {
console.log("Second thing done");
callback();
}, 1000);
}
function doYetAnotherThing(callback) {
setTimeout(function() {
console.log("Third thing done");
callback();
}, 1000);
}
doSomething(function() {
doSomethingElse(function() {
doYetAnotherThing(function() {
console.log("All things done");
});
});
});
프로미스는 비동기 작업의 최종 성공 또는 실패를 나타내는 객체이다.
지옥에서 벗어나는 방법이 바로 프로미스 입니다.
프로미스의 상태는 3가지가 있습니다.
작업의 최종 결과를 처리하는 데 사용할 수 있는 두 가지 방법이 있습니다.
// 프로미스 생성
const myPromise = new Promise((resolve, reject)=> {
resolve("the value we get from the promise");
});
// 프로미스 호출
myPromise.then(
data => {
console.log(data);
});
// the value we get from the promise
프로미스의 성공 또는 실패 여부와 무관하게 이전 프로미스에서 반환된 것을 계속 프로미스의 기반으로 사용하여 프로미스를 체이닝 할 수 있습ㄴ디ㅏ.
원하는 만큼 프로미스를 연결 할 수 있고, 이는 콜백지옥보다 간결하고 가독성 좋은 코드를 만들게 해줍니다.
firstAsyncOperation()
.then(secondAsyncOperation)
.then(thirdAsyncOperation)
.then(fourthAsyncOperation)
.then(function() {
console.log("All operations complete!");
})
.catch(function(error) {
console.log("An error occurred: " + error.message);
});
Promise.resolve() 와 Promise.reject()는 각각 자동으로 성공 혹은 실패하는 프로미스를 생성합니다.
let myPromise = Promise.resolve("hello world");
myPromise.then(function(value) {
console.log(value); // outputs "hello world"
});
let myPromise = Promise.reject(new Error("Something went wrong"));
myPromise.catch(function(error) {
console.log(error.message); // outputs "Something went wrong"
});
Promise.all()은 모든 프로미스가 성공할 경우에만 성공하는 하나의 프로미스를 반환합니다.
이와는 다르게, Promise.race()는 이터러블에 포함된 프로미스들 중 가장 먼저 성공 또는 실패한 결과를 반환합니다.
let promise1 = Promise.resolve(1);
let promise2 = Promise.resolve(2);
let promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
.then(function(values) {
console.log(values); // outputs [1, 2, 3]
})
.catch(function(error) {
console.log(error.message);
});
let promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 1000, 'one');
});
let promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 2000, 'two');
});
Promise.race([promise1, promise2])
.then(function(value) {
console.log(value); // outputs "one"
})
.catch(function(error) {
console.log(error.message);
});
제너레이터 함수는 원하는 만큼 코드 실행을 시작하거나 중지할 수 있는 함수 입니다.
function* generateArray(array) {
for(let i = 0; i < array.length; i++) {
yield array[i];
}
}
const arr = [1, 2, 3, 4, 5];
const gen = generateArray(arr);
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
console.log(gen.next().value); // 4
console.log(gen.next().value); // 5
function* generateSequence() {
yield 1;
yield 2;
yield 3;
}
const gen = generateSequence();
console.log(gen.next().value); // 1
console.log(gen.return("Terminating the sequence").value); // Terminating the sequence
console.log(gen.next().value); // undefined
function* generateError() {
try {
yield 1;
yield 2;
yield 3;
} catch(error) {
console.log(error.message);
}
}
const gen = generateError();
console.log(gen.next().value); // 1
console.log(gen.throw(new Error("Error occurred")));// Error occurred
function* generateSequence() {
yield 1;
yield 2;
yield 3;
}
const gen = generateSequence();
const promise = new Promise((resolve, reject) => {
const intervalId = setInterval(() => {
const next = gen.next();
if(next.done) {
clearInterval(intervalId);
resolve();
} else {
console.log(next.value);
}
}, 1000);
});
promise.then(() => {
console.log("Sequence complete");
});
JavaScript에서 프록시는 대상 개체의 동작을 사용자 지정하고 제어할 수 있도록 다른 개체에서 수행되는 작업을 가로채는 개체입니다.
const proxy = new Proxy(target, handler);
const obj = {
name: 'John',
age: 30
};
const proxy = new Proxy(obj, {
get(target, property) {
console.log(`Getting ${property} value`);
return target[property];
},
set(target, property, value) {
console.log(`Setting ${property} value to ${value}`);
target[property] = value;
},
deleteProperty(target, property) {
console.log(`Deleting ${property}`);
delete target[property];
}
});
console.log(proxy.name); // Getting name value, John
proxy.age = 35; // Setting age value to 35
delete proxy.age; // Deleting age