비동기 연산을 수행하고 연산이 종료되면 결과를 알려주겠다
고 약속
하는 것과 같다.const myPromise = new Promise((resolve, reject) => {
resolve('The value we get from the promise');
reject(new Error('this is our error'));
});
myPromise
.then((data) => {
console.log(data);
})
.catch((err) => {
console.error(err);
});
//The value we get from the promise
Promise.resolve('Hello. I successed').then(
//Promise.reject("Hello. I successed").then(
function (value) {
console.log('wow you successed');
},
function (value) {
console.log('no you failed.');
}
);
//resolve이면 wow you successed
//reject이면 no you failed.
코드 블록의 실행을 일시 중지했다가 필요한 시점에 재개할 수 있는
특수한 함수다. 비동기 처리를 동기 처리처럼 동작
하도록 구현했다.next()
를 호출하면 가장 가까운 yield <value>문
을 만날 때까지 실행이 지속된다(value를 생략할 수도 있는데, 이 경우엔 undefined가 된다). yield <value>
문을 만나면 실행이 멈추고 산출하고자 하는 값인 value가 바깥 코드에 반환됩니다.function* genFunc() {
const x = yield 1; //(1)
const y = yield x + 10; //(2)
return x + y; //(3)
}
const generator = genFunc(0);
let res = generator.next(); //(1)
console.log(res); // {value: 1, done: false} 처음 호출은 next메서드에 인수 전달안됨, const x = yield 1;
res = generator.next(15); //(2)
console.log(res); // {value: 25, done: false} 15를 x변수에 할당 const y = yield ('15'+10) = 25;
res = generator.next(100); //(3)
console.log(res); // {value: 115, done: true} 100을 y변수에 할당 세번째 코드 실행 return '15'+'100' =115
이터러블
이다. 제너레이터는 이터레이터를 어떻게 하면 쉽게 구현할지를 염두에 두며 자바스크립트에 추가되었다.for..of 반복문
을 사용해 값을 얻을 수 있다.스프레드 문법(...)
같은 관련 기능을 사용할 수 있다.function* generateSequence() {
yield 1;
yield 2;
yield 3;
}
let generator = generateSequence();
for(let value of generator) {
alert(value); // 1, 2, 3
}
제너레이터의 특수 문법 yield*를 사용하면 제너레이터를 다른 제너레이터에 ‘끼워 넣을 수’ 있습니다.
'yield’를 사용해 제너레이터 안·밖으로 정보 교환하기
function* gen() {
let ask1 = yield "2 + 2 = ?";
alert(ask1); // 4
let ask2 = yield "3 * 3 = ?"
alert(ask2); // 9
}
let generator = gen();
alert( generator.next().value ); // 첫번째 yield "2 + 2 = ?"
alert( generator.next(4).value ); // 4를 제너레이터 안 첫번째 yield로 전달하여 ask1=>4,
// 두번째 yield "3 * 3 = ?"
alert( generator.next(9).done ); // 9를 제너레이터 안 두번째 yield로 전달하여 ask2=>4,
// done: true 이므로 함수 종료
비동기 이터레이터(asynchronous iterator)
를 사용하면 비동기적으로 들어오는 데이터(네트워크를 통해 데이터가 여러 번에 걸쳐 들어오는 상황)를 필요에 따라 처리할 수 있다.비동기 제너레이터(asynchronous generator)
를 사용하면 이런 데이터를 좀 더 편리하게 처리할 수 있다.for-await-of
를 사용할 수 있다.const array = [1, 2, 3];
async function test() {
for await (const value of array) {
console.log(value);
}
}
test();
//1
//2
//3
for await...of
로 반복이 가능한 async 제너레이터
를 사용할 수 있다.//async 키워드를 붙이기만 하면 제너레이터 안에서 프라미스와 기타 async 함수를 기반으로 동작하는 await를 사용할 수 있습니다.
async function* generateSequence(start, end) {
for (let i = start; i <= end; i++) {
// await를 사용할 수 있습니다!
await new Promise((resolve) => setTimeout(resolve, 1000));
yield i;
}
}
(async () => {
let generator = generateSequence(1, 5);
for await (let value of generator) {
alert(value); // 1, 2, 3, 4, 5
}
})();
this 바인딩 : 바인딩이란 식별자와 값을 연결하는 과정을 의미한다. this 바인딩은 this(키워드로 분류되지만 식별자 역할을 한다)와 this가 가리킬 객체를 바인딩하는 것이다.
메서드 내부의 중첩 함수나 콜백 함수의 this 바인딩을 메서드의 this 바인딩과 일치시키기 위한 방법은 다음과 같다.
var value = 1;
const obj = {
value: 100,
foo() {
const that = this; //this 바인딩(obj)을 변수 that에 할당한다.
console.log("foo's this: ", that); // foo's this: {value: 100, foo: ƒ}
console.log("foo's this.value: ", that.value); //foo's this.value: 100
function bar() {
console.log("bar's this: ", that); // bar's this: {value: 100, foo: ƒ}
console.log("bar's this.value: ", that.value); //bar's this.value: 100
}
bar();
},
};
obj.foo();
var value = 1;
const obj = {
value: 100,
foo() {
//콜백 함수에 명시적으로 this를 바인딩한다
setTimeout(
function () {
console.log(this.value);
}.bind(this),
100
);
},
};
obj.foo();
function quickSort(arr) {
//3-2. 재귀는 리스트의 크기가 0이나 1이 될 때까지 반복된다
if (arr.length <= 1) {
return arr;
}
// 1. 리스트 가운데서 하나의 원소를 고른다. 이렇게 고른 원소를 피벗이라고 한다.
const pivot = arr[0];
const left = [];
const right = [];
// 2. 피벗 앞에는 피벗보다 값이 작은 모든 원소들이 오고, 피벗 뒤에는 피벗보다 값이 큰 모든 원소들이 오도록 피벗을 기준으로 리스트를 둘로 나눈다. 이렇게 리스트를 둘로 나누는 것을 분할이라고 한다. 분할을 마친 뒤에 피벗은 더 이상 움직이지 않는다.
for (let i = 1; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
//3. 분할된 두 개의 작은 리스트에 대해 재귀(Recursion)적으로 이 과정을 반복한다.
return quickSort(left).concat(pivot, quickSort(right)); //재귀함수
}