1. μ λλ μ΄ν° ν¨μ
μ½λ λΈλ‘μ μ€νμ μΌμ μ€μ§νλ€κ° νμν μμ μ μ¬κ°ν μ μλ νΉμν ν¨μ
- function* λ‘ μ μν ν¨μ.
- νΈμΆνλ©΄ λ°λ‘ μ€νλμ§ μκ³ “μ λλ μ΄ν° κ°μ²΄(μ΄ν°λ μ΄ν°)”λ₯Ό λ°ν.
- μ΄ κ°μ²΄μλ next(), return(), throw() λ©μλκ° μκ³ ,
- yield μ§μ μμ μ€νμ΄ μΌμμ€μ§/μ¬κ°λλ€.
- next()λ₯Ό νΈμΆν λλ§λ€ λ€μ yieldκΉμ§ μ§νλλ€.
μ λλ μ΄ν° vs μΌλ°ν¨μ
1. μ λλ μ΄ν° ν¨μλ ν¨μ νΈμΆμμκ² ν¨μ μ€νμ μ μ΄κΆμ μλν μ μλ€
μΌλ° ν¨μλ νΈμΆνλ©΄ μ μ΄κΆμ΄ ν¨μμκ² λμ΄κ°κ³ , ν¨μκ° νΈμΆλ μ΄ν ν¨μ μ€νμ μ μ΄ν μ μλ€ → ν¨μ λ°μμ μ€ν μ€μΈ ν¨μλ₯Ό λ©μΆκ±°λ μ¬κ°ν μ μλ€
μ λλ μ΄ν° ν¨μλ ν¨μ νΈμΆμκ° ν¨μ μ€νμ μΌμ μ€μ§μν€κ±°λ μ¬κ°μν¬ μ μλ€.
function* steps() {
console.log('A'); // μμ
yield 1; // β΅ μ¬κΈ°μ μΌμμ€μ§ (κ° 1μ λ°μΌλ‘ 보λ)
console.log('B'); // μ¬κ°λλ©΄ μ¬κΈ°λΆν°
yield 2; // β΅ λ μ€μ§ (κ° 2)
console.log('C'); // μ¬κ°λλ©΄ μ¬κΈ°λΆν°
return 3; // μ’
λ£ (κ° 3)
}
const it = steps();
console.log(it.next()); // { value: 1, done: false } βΆ 'A'κΉμ§ μ€ν ν 첫 yieldμμ λ©μΆ€
console.log(it.next()); // { value: 2, done: false } βΆ 'B' μ€ν ν λ λ²μ§Έ yieldμμ λ©μΆ€
console.log(it.next()); // { value: 3, done: true } βΆ 'C' μ€ν ν returnμΌλ‘ λ
2. μ λλ μ΄ν° ν¨μλ ν¨μ νΈμΆμμ ν¨μμ μνλ₯Ό μ£Όκ³ λ°μ μ μλ€
μΌλ° ν¨μλ₯Ό νΈμΆνλ©΄ λ§€κ°λ³μλ₯Ό ν΅ν΄ ν¨μ μΈλΆμμ κ°μ μ£Όμ λ°κ³ ν¨μ μ½λλ₯Ό μΌκ΄ μ€ννμ¬ κ²°κ³Όκ°μ ν¨μ μΈλΆλ‘ λ°ν.
μ¦, ν¨μκ° μ€νλκ³ μλ λμμλ ν¨μ μΈλΆμμ ν¨μ λ΄λΆλ‘ κ°μ μ λ¬νμ¬ ν¨μμ μνλ₯Ό λ³κ²½ X
μ λλ μ΄ν° ν¨μλ ν¨μ νΈμΆμμκ² μνλ₯Ό μ λ¬ν μ μκ³ , ν¨μ νΈμΆμλ‘λΆν° μνλ₯Ό μ λ¬λ°μ μ μλ€.
3. μ λλ μ΄ν° ν¨μλ₯Ό νΈμΆνλ©΄ μ λλ μ΄ν° κ°μ²΄λ₯Ό λ°ν
μΌλ° ν¨μλ ν¨μμ½λλ₯Ό μ€ννκ³ κ°μ λ°ν
μ λλ μ΄ν° ν¨μ : ν¨μ μ½λλ₯Ό μ€ννλ κ²μ΄ μλλΌ μ΄ν°λ¬λΈμ΄λ©΄μ λμμ μ΄ν°λ μ΄ν°μΈ μ λλ μ΄ν° κ°μ²΄λ₯Ό λ°ν.
function* askName() {
const name = yield 'μ΄λ¦μ΄ λμμ?'; // a
return `μλ
νμΈμ, ${name}λ!`; // b
}
const it2 = askName(); // A
console.log(it2.next()); // B
console.log(it2.next('μμ')); // C
A. askNameμ function* μΌλ‘ μ μλμμΌλ―λ‘ μ λλ μ΄ν° ν¨μ, μ§κΈμ μ½λκ° μ€νλμ§ μμ
λμ μ λλ μ΄ν° κ°μ²΄ it2λ₯Ό λ°ν
→ it2λ next/return/throw λ©μλλ₯Ό κ°μ§ μ΄ν°λ μ΄ν°
B. it2. next() νΈμΆ
- μ λλ μ΄ν° μ€νμ΄ μμλμ΄ yield μ€
- a μ€μμ yield 'μ΄λ¦μ΄ λμμ?'λ₯Ό λ§λλ©΄:
- λ°μΌλ‘ λ΄λ³΄λ΄λ κ°(value): 'μ΄λ¦μ΄ λμμ?'
- μΌμ μ€μ§ μμΉ: a μ€μ yield ννμ λ°λ‘ λ€ (λμ μμ μ€λ₯Έμͺ½)
- next()μ λ°ν: { value: 'μ΄λ¦μ΄ λμμ?', done: false }
- μ€μ: μ΄ μκ° aμ const name = …λ μμ§ μλ£λμ§ μμμ.
- yieldλ “κ°μ λ°μ λ΄λ³΄λ΄κ³ λ©μΆ” μνμΌ λΏ
C. it2.next(’μμ’)
- λ©μΆ° μλ μ§μ (β μ yield)μμ λ€μ μ¬κ°λλ€.
- μ΄λ² next('μμ')λ‘ μ λ¬ν κ°μ, λ°λ‘ μ§μ yield ννμμ κ²°κ³Όκ° λλ€.
- μ¦, const name = (yield 'μ΄λ¦μ΄ λμμ?')μμ
- nameμλ 'μμ'κ° λμ λλ€.
- μ΄μ΄μ b μ€ μ€ν: return μλ νμΈμ, ${name}λ!``
- → μ΅μ’ λ°νκ° 'μλ νμΈμ, μμλ!'μ λ΄λ³΄λ΄λ©° μ’ λ£.
- next('μμ')μ λ°ν: { value: 'μλ νμΈμ, μμλ!', done: true }
2. μ λλ μ΄ν° ν¨μμ μ μ
- function* ν€μλλ‘ μ μΈ
- νλ μ΄μμ yield ννμμ ν¬ν¨
- λλ¨Έμ§λ μΌλ° ν¨μ μ μμ λμΌ
// μ λλ μ΄ν° ν¨μ μ μΈλ¬Έ
function* genDecFunc() {
yield 1;
}
// μ λλ μ΄ν° ν¨μ ννμ
const genExpFunc = function* () {
yield 1;
};
// μ λλ μ΄ν° λ©μλ
const obj = {
* genObjMethod() {
yield 1;
}
};
// μ λλ μ΄ν° ν΄λμ€ λ©μλ
class MyClass {
* genClsMethod() {
yield 1;
}
}
← *(μ μ€ν°λ¦¬μ€ν¬) μ μμΉλ functonκ³Ό ν¨μλͺ μ¬μ΄λ©΄ λ€ κ°λ₯
μΌκ΄μ±μ μν΄ function* κΆμ₯
function* genFunc() { yield 1; } //κΆμ₯
function * genFunc() { yield 1; }
function *genFunc() { yield 1; }
function*genFunc() { yield 1; }
μ λλ μ΄ν° ν¨μλ νμ΄ν ν¨μλ‘ μ μ X
const genArrowFunc = * () => {
yield 1; //μ λλ μ΄ν° ν¨μκ° μλλ―λ‘ yield μ¬μ© λΆκ°
}; // SyntaxError: Unexpected token '*'
- μ λλ μ΄ν° νκΈ°λ function* λλ **async function**μλ§ λΆλ μ μ© λ¬Έλ²
- νμ΄ν ν¨μ λ¬Έλ²( () => {} )μλ λ₯Ό λΆμΌ μλ¦¬κ° μμ μμ
- μ¦, νμ΄ν ν¨μμ λ¬Έλ² κ·μΉμ * ν ν°(μ λλ μ΄ν° νμ§)μ΄ ν¬ν¨λμ΄ μμ§ μκΈ° λλ¬Έμ νμκ° *λ₯Ό λ³΄κ³ SyntaxErrorλ₯Ό λΈλ€
μ λλ μ΄ν° ν¨μλ new μ°μ°μμ ν¨κ» μμ±μ ν¨μλ‘ νΈμΆX
function* genFunc() {
yield 1;
}
new genFunc(); // TypeError: genFunc is not a constructor
- newκ° λμνλ €λ©΄ ν¨μκ° μμ±μ(constructible) μ¬μΌ νλ€
- μ¦, λ΄λΆμ μΌλ‘ [[Construct]]λΌλ λμμ κ°μ ΈμΌ νλ€
- μ λλ μ΄ν° ν¨μλ “μμ±μ”κ° μλλλ€. νΈμΆνλ©΄ κ°μ²΄λ₯Ό μμ±νλ λμ “μ λλ μ΄ν°(μ΄ν°λ μ΄ν°) κ°μ²΄”λ₯Ό λ°ννλ ν©ν 리 μν λ§ ν¨
- → new genFunc()λ₯Ό νλ©΄ TypeError: not a constructor
3. μ λλ μ΄ν° κ°μ²΄
- μ λλ μ΄ν° ν¨μλ₯Ό νΈμΆνλ©΄ μΌλ° ν¨μμ²λΌ ν¨μ μ½λ λΈλ‘μ μ€ννλ κ²μ΄ μλλΌ μ λλ μ΄ν° κ°μ²΄λ₯Ό μμ±ν΄ λ°ν
- μ λλ μ΄ν° ν¨μκ° λ°νν μ λλ μ΄ν° κ°μ²΄λ μ΄ν°λ¬λΈμ΄λ©΄μ λμμ μ΄ν°λ μ΄ν°
→ Symbol.iterator λ©μλλ₯Ό μμλ°λ μ΄ν°λ¬λΈ
→ value, done νλ‘νΌν°λ₯Ό κ°μ§λ μ΄ν°λ μ΄ν° result κ°μ²΄λ₯Ό λ°ννλ next λ©μλ μμ νλ μ΄ν°λ μ΄ν°
function* steps() {
console.log('A'); // μμ
yield 1; // β΅ μ¬κΈ°μ μΌμμ€μ§ (κ° 1μ λ°μΌλ‘ 보λ)
console.log('B'); // μ¬κ°λλ©΄ μ¬κΈ°λΆν°
yield 2; // β΅ λ μ€μ§ (κ° 2)
console.log('C'); // μ¬κ°λλ©΄ μ¬κΈ°λΆν°
return 3; // μ’
λ£ (κ° 3)
}
const it = steps();
console.log(it.next()); // { value: 1, done: false } βΆ 'A'κΉμ§ μ€ν ν 첫 yieldμμ λ©μΆ€
console.log(it.next()); // { value: 2, done: false } βΆ 'B' μ€ν ν λ λ²μ§Έ yieldμμ λ©μΆ€
console.log(it.next()); // { value: 3, done: true } βΆ 'C' μ€ν ν returnμΌλ‘ λ
→ next λ©μλ : value, done νλ‘νΌν°λ₯Ό κ°μ§λ μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄λ₯Ό λ°ν
// μ λλ μ΄ν° ν¨μ
function* genFunc() {
yield 1;
yield 2;
yield 3;
}
// μ λλ μ΄ν° ν¨μλ₯Ό νΈμΆνλ©΄ μ λλ μ΄ν° κ°μ²΄λ₯Ό λ°ννλ€.
const generator = genFunc();
// μ λλ μ΄ν° κ°μ²΄λ μ΄ν°λ¬λΈμ΄λ©΄μ λμμ μ΄ν°λ μ΄ν°λ€.
// μ΄ν°λ¬λΈμ Symbol.iterator λ©μλλ₯Ό μ§μ ꡬννκ±°λ νλ‘ν νμ
체μΈμ ν΅ν΄ μμλ°μ κ°μ²΄λ€.
console.log(Symbol.iterator in generator); // true
// μ΄ν°λ μ΄ν°λ next λ©μλλ₯Ό κ°λλ€.
console.log('next' in generator); // true
μΌλ°ν¨μμλ μλ next, return, throw
next
next return throw
| value | yield λ κ° | μΈμλ‘ μ λ¬ λ°μ κ° | undefined |
| done | λ€μ λ¨μμμΌλ©΄ false, returnμΌλ‘ λ€μ μμΌλ©΄ true | true | true |
μ λλ μ΄ν° ν¨μμ yield ννμκΉμ§ μ½λ λΈλμ μ€ννκ³
- value : yield λ κ°
- done : λ€μ λ¨μΌλ©΄ false, returnμ λ§λκ³ λλλ©΄ true
μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄λ₯Ό λ°ν
function* genFunc() {
try {
yield 1;
yield 2;
yield 3;
} catch (e) {
console.error(e);
}
}
const generator = genFunc();
console.log(generator.next()); // {value: 1, done: false}
console.log(generator.return('End!')); // {value: "End!", done: true}
return
- value : μΈμλ‘ μ λ¬λ°μ κ°
- done : true
μ΄λ¬ν μ΄ν° 리μ νΈ κ°μ²΄λ₯Ό λ°ν
throw
- μΈμλ‘ μ λ¬λ°μ μλ¬λ₯Ό λ°μμν€κ³
- value : undefined
- done : true
μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄λ₯Ό λ°ν
function* genFunc() {
try {
yield 1;
yield 2;
yield 3;
} catch (e) {
console.error(e);
}
}
const generator = genFunc();
console.log(generator.next()); // {value: 1, done: false}
console.log(generator.throw('Error!')); // {value: undefined, done: true}
4. μ λλ μ΄ν°μ μΌμ μ€μ§μ μ¬κ°
yield ν€μλ → μ€ν μ€μ§ or yield ν€μλ λ€μ μ€λ ννμμ νκ³Ό κ²°κ³Όλ₯Ό μ λλ μ΄ν° ν¨μ νΈμΆμμκ² λ°ν
next λ©μλ → νμν μμ μ λ€μ μ¬κ°
// μ λλ μ΄ν° ν¨μ
function* genFunc() {
yield 1;
yield 2;
yield 3;
}
// μ λλ μ΄ν° ν¨μλ₯Ό νΈμΆνλ©΄ μ λλ μ΄ν° κ°μ²΄λ₯Ό λ°ν
// μ΄ν°λ¬λΈμ΄λ©΄μ λμμ μ΄ν°λ μ΄ν°μΈ μ λλ μ΄ν° κ°μ²΄λ next λ©μλλ₯Ό κ°λλ€.
const generator = genFunc();
// μ²μ next λ©μλλ₯Ό νΈμΆνλ©΄ 첫 λ²μ§Έ yield ννμκΉμ§ μ€νλκ³ μΌμ μ€μ§
// next λ©μλλ μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄({value, done})λ₯Ό λ°ν
// value : 첫 λ²μ§Έ yield ννμμμ yieldλ κ° 1μ΄ ν λΉ
// done : μ λλ μ΄ν° ν¨μκ° λκΉμ§ μ€νλμλμ§λ₯Ό λνλ΄λ falseκ° ν λΉ
console.log(generator.next()); // {value: 1, done: false}
// λ€μ next λ©μλλ₯Ό νΈμΆνλ©΄ λ λ²μ§Έ yield ννμκΉμ§ μ€νλκ³ μΌμ μ€μ§
// next -> ({value, done})λ₯Ό λ°ν
// value : λ λ²μ§Έ yield ννμμμ yieldλ κ° 2κ° ν λΉ
// done : μ λλ μ΄ν° ν¨μκ° λκΉμ§ μ€νλμλμ§λ₯Ό λνλ΄λ falseκ° ν λΉ
console.log(generator.next()); // {value: 2, done: false}
// λ€μ next λ©μλλ₯Ό νΈμΆνλ©΄ μΈ λ²μ§Έ yield ννμκΉμ§ μ€νλκ³ μΌμ μ€μ§
// next -> ({value, done})λ₯Ό λ°ν
// value : μΈ λ²μ§Έ yield ννμμμ yieldλ κ° 3μ΄ ν λΉ
// done : μ λλ μ΄ν° ν¨μκ° λκΉμ§ μ€νλμλμ§λ₯Ό λνλ΄λ falseκ° ν λΉ
console.log(generator.next()); // {value: 3, done: false}
// λ€μ next λ©μλλ₯Ό νΈμΆνλ©΄ λ¨μ yield ννμμ΄ μμΌλ―λ‘ μ λλ μ΄ν° ν¨μμ λ§μ§λ§κΉμ§ μ€ννλ€.
// next -> ({value, done})λ₯Ό λ°ν
// value -> undefinedκ° ν λΉ
// done : μ λλ μ΄ν° ν¨μκ° λκΉμ§ μ€νλμμμ λνλ΄λ trueκ° ν λΉ
console.log(generator.next()); // {value: undefined, done: true}
μ λλ μ΄ν° κ°μ²΄μ next λ©μλμ μ λ¬ν μΈμλ μ λλ μ΄ν° ν¨μμ yield ννμμ ν λΉλ°λ λ³μμ ν λΉ.
yield ννμμ ν λΉλ°λ λ³μμ yield ννμμ νκ° κ²°κ³Όκ° ν λΉλμ§ μλ κ²μ μ£Όμ
function* genFunc() {
// 첫 next()λ₯Ό νΈμΆνλ©΄ 첫 λ²μ§Έ yieldκΉμ§ μ€νλκ³ μΌμ μ€μ§λλ€.
// μ΄λ next()μ λ°ν κ°μ²΄λ { value: 1, done: false }μ΄λ©°,
// μμ§ xμλ μ무 κ°λ λ€μ΄κ°μ§ μμλ€(λ€μ next(arg)λ‘ κ²°μ λ¨).
const x = yield 1;
// λ λ²μ§Έ next(100)μ νΈμΆνλ©΄, μ λ¬ν 100μ΄ λ°λ‘ μ§μ yield ννμμ κ°μ΄ λμ΄ xμ λμ
λλ€.
// μ΄μ΄μ μ€νλμ΄ λ λ²μ§Έ yieldμμ (x + 10) = 110μ λ°μΌλ‘ λ΄λ³΄λ΄κ³ μΌμ μ€μ§νλ€.
// λ§μ°¬κ°μ§λ‘ μμ§ yμλ μ무 κ°λ λ€μ΄μ§ μμλ€.
const y = yield (x + 10);
// μΈ λ²μ§Έ next(50)μ νΈμΆνλ©΄, μ λ¬ν 50μ΄ μ§μ yield ννμμ κ°μ΄ λμ΄ yμ λμ
λλ€.
// μ΄μ΄μ ν¨μ λκΉμ§ μ€νλλ©°, λ°νκ° x + y = 100 + 50 = 150μ λ΄λ³΄λ΄κ³ done: trueλ‘ μ’
λ£νλ€.
return x + y;
}
// μ λλ μ΄ν° ν¨μλ₯Ό νΈμΆνλ©΄ 'μ€νμ 미룬' μ λλ μ΄ν° κ°μ²΄(μ΄ν°λ μ΄ν°)λ₯Ό λ°ννλ€.
const generator = genFunc(0); // μΈμ 0μ 무μλ¨(첫 next μ κΉμ§λ μ΄λ€ μΈμλ μ λ¬λμ§ μμ).
// 1) 첫 νΈμΆ: μΈμλ₯Ό μ£ΌλλΌλ 무μλλ€. 첫 λ²μ§Έ yield(1)κΉμ§ μ€ννκ³ λ©μΆλ€.
let res = generator.next();
console.log(res); // { value: 1, done: false }
// 2) λ λ²μ§Έ νΈμΆ: next(100)
// μ΄μ yieldμ κ²°κ³Όκ° λμ΄ x = 100μ΄ λλ€.
// μ΄μ΄μ λ λ²μ§Έ yieldμμ (x + 10) = 110μ λ΄λ³΄λ΄κ³ λ©μΆλ€.
res = generator.next(100);
console.log(res); // { value: 110, done: false }
// 3) μΈ λ²μ§Έ νΈμΆ: next(50)
// μ΄μ yieldμ κ²°κ³Όκ° λμ΄ y = 50μ΄ λλ€.
// ν¨μκ° λκΉμ§ μ€νλλ©° x (100) + y (50) = 150μ λ°ννκ³ μ’
λ£νλ€.
res = generator.next(50);
console.log(res); // { value: 150, done: true }
- next()λ‘ μ λ¬ν μΈμλ μ΄μ yield ννμμ ν λΉ λ°λ λ³μμ λ€μ΄κ°
- → 맨 μ²μμΌλ‘ μ λ¬ν μΈμλ 무μλλ€.
5. μ λλ μ΄ν°μ νμ©
1. μ΄ν°λ¬λΈκ΅¬ν
μ λλ μ΄ν° ν¨μλ₯Ό μ΄μ©νλ©΄ μ΄ν°λ μ΄μ νλ‘ν μ½μ μ€μν΄ μ΄ν°λ¬λΈμ μμ±νλ λ°©μλ³΄λ€ κ°λ¨ν μ΄ν°λ¬λΈμ ꡬνν μ μλ€
→ μ? μ λλ μ΄ν° ν¨μκ° μ΄ν°λ¬λΈνλ©΄μ λμμ μ΄ν°λ μ΄ν°μ΄λ―λ‘
// 무ν μ΄ν°λ¬λΈμ μμ±νλ ν¨μ
const infiniteFibonacci = (function () {
let [pre, cur] = [0, 1]; // β¬
οΈ νμλ μν(ν΄λ‘μ ): μ΄μ κ°/νμ¬κ° μ μ₯
return {
[Symbol.iterator]() { return this; }, // β¬
οΈ μ΄ν°λ¬λΈ: for..ofκ° λΆλ₯Ό λ
next() { // β¬
οΈ μ΄ν°λ μ΄ν°: ν κ±Έμ μ§ν
[pre, cur] = [cur, pre + cur]; // νΌλ³΄λμΉ μ μ§
return { value: cur }; // done μλ΅ => 무ν
}
};
}());
// infiniteFibonacciλ 무ν μ΄ν°λ¬λΈμ΄λ€.
for (const num of infiniteFibonacci) {
if (num > 10000) break;
console.log(num); // 1 2 3 5 8...2584 4181 6765
}
- IIFE(μ¦μ μ€ν ν¨μ) κ° ν λ² μ€νλμ΄ κ°μ²΄λ₯Ό λ°ννκ³ , κ·Έ λ°νλ κ°μ²΄λ₯Ό infiniteFibonacciμ λ΄μ.
- λ°νλ κ°μ²΄λ:
- Symbol.iterator λ©μλκ° μμ΄μ μ΄ν°λ¬λΈμ΄κ³ ,
- next() λ©μλκ° μμ΄μ μ΄ν°λ μ΄ν°μ΄κΈ°λ ν¨.
- return this λλΆμ “μ΄ν°λ¬λΈ === μ΄ν°λ μ΄ν°” νν(= μκΈ° μμ μ΄ λ°λ³΅μ).
μ¦, for (const x of infiniteFibonacci)κ° μμλλ©΄,
- μμ§μ infiniteFibonacci[Symbol.iterator]()λ₯Ό νΈμΆ → μκΈ° μμ μ λ°μ
- κ·Έλ¦¬κ³ λ§€ λ°λ³΅λ§λ€ next()λ₯Ό νΈμΆν΄ { value, done }λ₯Ό λ°μ
[pre, cur] = [cur, pre + cur];
return { value: cur };
νΈμΆ κ°±μ ν (pre, cur) λ°ν value
| 1λ²μ§Έ next | (1, 1) | 1 |
| 2λ²μ§Έ next | (1, 2) | 2 |
| 3λ²μ§Έ next | (2, 3) | 3 |
| 4λ²μ§Έ next | (3, 5) | 5 |
| 5λ²μ§Έ next | (5, 8) | 8 |
| … | … | … |
μμ μ½λλ³΄λ€ μ λλ μ΄ν° ν¨μλ₯Ό μ¬μ©νλ©΄ λ κ°λ¨νλ€.
// 무ν μ΄ν°λ¬λΈμ μμ±νλ μ λλ μ΄ν° ν¨μ
const infiniteFibonacci = (function* () {
let [pre, cur] = [0, 1];
while (true) {
[pre, cur] = [cur, pre + cur];
yield cur;
}
}());
// infiniteFibonacciλ 무ν μ΄ν°λ¬λΈμ΄λ€.
for (const num of infiniteFibonacci) {
if (num > 10000) break;
console.log(num); // 1 2 3 5 8...2584 4181 6765
}
- yield cur κ° μλ λΆλΆκΉμ§ νΈμΆν ν λ€μ nextμμλ while trueλ‘ λμ΄ μμΌλ―λ‘ λ€μ while λ¬Έμ λ°λ³΅
2. λΉλκΈ° μ²λ¦¬
next λ©μλμ yield ννμμ ν΅ν΄ ν¨μ νΈμΆμμ ν¨μμ μνλ₯Ό μ£Όκ³ λ°μ μ μλ€
→ νλ‘λ―Έμ€λ₯Ό μ¬μ©ν λΉλκΈ° μ²λ¦¬λ₯Ό λκΈ° μ²λ¦¬μ²λΌ ꡬν
→ νλ‘λ―Έμ€μ νμ μ²λ¦¬ λ©μλ then/catch/finally μμ΄ λΉλκΈ° μ²λ¦¬ κ²°κ³Ό λ°ννλλ‘ κ΅¬ν κ°λ₯
const fetch = require('node-fetch');
// π§© μ λλ μ΄ν° μ€νκΈ°
const async = generatorFunc => {
const generator = generatorFunc(); // 1οΈβ£ μ λλ μ΄ν° κ°μ²΄ μμ±
const onResolved = arg => {
const result = generator.next(arg); // 2οΈβ£ next() μ€ν
return result.done
? result.value // 7οΈβ£ μ λλ μ΄ν° μλ£ μ value λ°ν
: result.value.then(res => onResolved(res)); // 3οΈβ£ νλ‘λ―Έμ€ resolve ν μ¬κ· νΈμΆ
};
return onResolved; // 4οΈβ£ ν΄λ‘μ (onResolved) λ°ν
};
// π μ λλ μ΄ν° ν¨μ μ€ν
(async(function* fetchTodo() { // 5οΈβ£ async ν¨μ νΈμΆ
const url = '<https://jsonplaceholder.typicode.com/todos/1>';
const response = yield fetch(url); // 6οΈβ£ fetch() → νλ‘λ―Έμ€ λ°ν
const todo = yield response.json(); // 8οΈβ£ response.json() → νλ‘λ―Έμ€ λ°ν
console.log(todo); // {userId: 1, id: 1, title: 'delectus aut autem', completed: false}
})()); // 9οΈβ£ λ°νλ onResolved() μ¦μ μ€ν
1οΈβ£ μ λλ μ΄ν° κ°μ²΄ μμ±
- async(generatorFunc)κ° νΈμΆλλ©΄ λ΄λΆμμ generatorFunc()—μ¦ fetchTodo() μ λλ μ΄ν° ν¨μκ° μ€νλ§ ν΄μ(μμ X) μ λλ μ΄ν° κ°μ²΄(generator)λ₯Ό λ§λ λ€.
- μμ§ fetchTodo λ³Έλ¬Έμ 첫 μ€λ μ§νλμ§ μμμ. μ λλ μ΄ν°λ next()κ° λ€μ΄μ€λ©΄ κ·ΈλλΆν° λλ€.
- onResolved λ generator λ₯Ό μΊ‘μ³(κΈ°μ΅)νκ³ μμΌλ―λ‘, μΈμ λ μ§ νΈμΆλλ©΄ generator.next() μ€ν κ°λ₯ → ν΄λ‘μ Έ
2οΈβ£ 첫 λ²μ§Έ next() νΈμΆ
- onResolved()κ° μ²μ νΈμΆλλ€(μΈμ μμ → undefined).
- λ΄λΆμμ generator.next(undefined) μ€ν → fetchTodoκ° μ²μμΌλ‘ λ¬λ¦¬κΈ° μμ.
- const response = yield fetch(url); κΉμ§ μ§νλκ³ λ©μΆ€.
- μ΄λ result = { value: Promise<Response>, done: false }.
- μ¦, **λ©μΆ μμΉλ yield fetch(url)*μ΄κ³ , valueλ fetch(url)μ΄ λ°νν νλ‘λ―Έμ€.
3οΈβ£ νλ‘λ―Έμ€κ° ν΄κ²°λλ©΄ μ¬κ· μ¬κ°
- done:falseμ΄λ―λ‘ result.value.then(res => onResolved(res))λ‘ λ±λ‘.
- fetch(url)μ΄ resolveλλ©΄, κ·Έ κ²°κ³Ό(Response κ°μ²΄)λ₯Ό λ€κ³ λ€μ onResolved(res) νΈμΆ(μ¬κ· μ§μ ).
- μ ν¬μΈνΈκ° ν΅μ¬: yieldμμ “λ©μΆ” μ λλ μ΄ν°λ₯Ό, νλ‘λ―Έμ€κ° λλ κ°μΌλ‘ λ€μ κΉ¨μμ€λ€λ κ².
4οΈβ£ ν΄λ‘μ (onResolved) λ°ν
- 1οΈβ£ λ¨κ³μμ μΈκΈν λλ‘, async()λ onResolvedλ₯Ό 리ν΄νκ³ λλλ€.
- μ½λμμλ μ΄ λ°νκ°μ μ¦μ μ€ν(IIFE) νλλ‘ μ μ΄λ¨κΈ° λλ¬Έμ(→ 9οΈβ£) νλ¦μ΄ μ΄μ΄μ§λ€.
- κΈ°μ΅νμ: onResolvedλ generatorλ₯Ό μΊ‘μ²ν΄μ, μΈμ λ μ§ μΈλΆμμ λ€μ next()λ₯Ό λλ¬ μ΄μ΄ λ¬λ¦΄ μ μκ² λ§λ λ²νΌ κ°μ μ‘΄μ¬.
5οΈβ£ λ°νλ onResolved μ¦μ μ€ν(IIFE)
- μμ€μ (... )(); λΆλΆμ΄ λ°λ‘ μ΄κ±°.
- async(fetchTodo) → onResolved λ°ν → κ³§λ°λ‘ onResolved() νΈμΆ.
- μ¬κΈ°μ 2οΈβ£μ΄ μμλλ€κ³ λ΄λ λλ€(μ²μ next()κ° νΈλ¦¬κ±°λλ μ§μ ).
6οΈβ£ λ λ²μ§Έ next(res) — Response μ£Όμ
- 3οΈβ£μμ λ±λ‘νλ .thenμ΄ λΆλ¦¬λ©΄, onResolved(res)κ° νΈμΆλλ€.
- λ΄λΆμμ generator.next(res) μ€ν → λ°©κΈ λ°μ Responseκ° fetchTodoμ response λ³μμ ν λΉλλ©΄μ λ€μ μ€λ‘ μ§ν.
- μ΄μ const todo = yield response.json(); κΉμ§ κ°μ λ€μ λ©μΆ€.
- μ΄λ² result = { value: Promise<Todo>, done: false }.
8οΈβ£ μΈ λ²μ§Έ next(todo) — λ°μ΄ν° μ£Όμ
- response.json()μ΄ resolveλλ©΄ λ onResolved(todo) νΈμΆ.
- generator.next(todo) μ€ν → todoκ° λ³μμ ν λΉλκ³ , console.log(todo)κΉμ§ λ.
- μ λλ μ΄ν° ν¨μ λ³Έλ¬Έμ΄ λλ¬μΌλ―λ‘ λ€μ next() κ²°κ³Όλ
- result = { value: undefined, done: true }.
9οΈβ£ μλ£ μ²λ¦¬ (done:true)
- done:trueμ΄λ―λ‘ onResolvedλ result.value—μ¦ undefined—λ₯Ό κ·Έλλ‘ λ¦¬ν΄νκ³ μ¬κ· μ’ λ£.
- μ¬κ·λ‘ μμλ onResolved(...) νΈμΆλ€μ΄ μμ°¨μ μΌλ‘ μΈμμΈλλλ©° λͺ¨λ undefinedλ‘ λλλ€.
7οΈβ£ μ΅μ’ λ°νκ°μ undefined
- μ λλ μ΄ν°μ λ°νκ°(μ¬κΈ°μλ λͺ μμ return μμΌλ undefined)μ΄ μ΅μ’ κ°.
- μ¦, μ΄ “μ€νκΈ°”λ λΉλκΈ° λμμ μμ°¨λ‘ νμ΄μ£Όλ μν λ§ νκ³ , νΉλ³ν κ°μ λλ €μ£Όμ§ μλλ€.
μ μ½λλ₯Ό async/awaitμ μ¬μ©νλ©΄ μ λλ μ΄ν° ν¨μμ κ°μ΄ μ€νν νμ μλ€
const fetch = require('node-fetch'); // 1οΈβ£ node νκ²½μμ fetch μ¬μ©μ μν λͺ¨λ
const co = require('co'); // 2οΈβ£ co: μ λλ μ΄ν° κΈ°λ° λΉλκΈ° μ€νκΈ°
co(function* fetchTodo() { // 3οΈβ£ co()κ° μ λλ μ΄ν° ν¨μλ₯Ό μ€ν
const url = '<https://jsonplaceholder.typicode.com/todos/1>';
const response = yield fetch(url); // 4οΈβ£ fetch() → Promise λ°ν → coκ° resolveλ λκΉμ§ κΈ°λ€λ¦Ό
const todo = yield response.json(); // 5οΈβ£ response.json() → Promise λ°ν → coκ° resolveλ λκΉμ§ κΈ°λ€λ¦Ό
console.log(todo); // 6οΈβ£ μ΅μ’
λ°μ΄ν° μΆλ ₯
});
3οΈβ£ co(function* fetchTodo() { ... })κ° νΈμΆ
co()λ μ΄ μ λλ μ΄ν° ν¨μλ₯Ό μ€ννλ©΄μ λ΄λΆμμ next()λ₯Ό κ³μ λλ¬μ£Όλ μν
→ coκ° λμ “νλ‘λ―Έμ€κ° λλ λλ§λ€ μμμ λ€μ next() νΈμΆ → λΉλκΈ° νλ¦μ μλμΌλ‘ μμλλ‘ μ΄μ΄μ£Όλ κ΄λ¦¬μ
4οΈβ£ μ λλ μ΄ν° λ΄λΆμμ const response = yield fetch(url);μ΄ μ€ν
- fetch(url)μ λ€νΈμν¬ μμ²μ 보λ΄κ³ Promise<Response>λ₯Ό λ°ν
- yieldλ₯Ό λ§λλ©΄ ν¨μ λ©μΆ€
- co λ fetch(url)μ΄ μλ£λ λκΉμ§ κΈ°λ€λ Έλ€κ° κ²°κ³Ό Response κ°μ²΄λ₯Ό λ€μ next()μΈμλ‘ λ£μ΄μ μ λλ μ΄ν° μ¬κ°
5οΈβ£ const todo = yield response.json();
- response.json() μμ λΉλκΈ° ν¨μμ΄λ―λ‘ Promiseλ₯Ό λ°ν
- λ ν λ² yieldμμ λ©μΆκ³ , coκ° κΈ°λ€λ¦½λλ€.
- κ·Έ Promiseκ° resolveλλ©΄, μ¦ JSON λ³νμ΄ λλλ©΄
- κ·Έ κ²°κ³Ό κ°μ²΄(todo λ°μ΄ν°)κ° next() μ μΈμλ‘ μ λ¬λμ΄ todo λ³μμ μ μ₯
6οΈβ£ console.log(todo)
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
6. async/await
μ λλ μ΄ν°λ₯Ό μ¬μ©ν΄μ λΉλκΈ° μ²λ¦¬λ₯Ό λκΈ° μ²λ¦¬μ²λΌ λμνλλ‘ κ΅¬ννλ©΄ μ½λκ° κΈΈμ΄μ Έμ κ°λ μ± μ ν
→ ES8λΆν° async/await λμ
- νλ‘λ―Έμ€ κΈ°λ° λμ
- then/catch/fianlly νμ μ²λ¦¬ λ©μλμ μ½λ°± ν¨μλ₯Ό μ λ¬ν΄μ λΉλκΈ° μ²λ¦¬ κ²°κ³Όλ₯Ό νμ μ²λ¦¬ν νμ μμ΄ λ§μΉ λκΈ° μ²λ¦¬μ²λΌ νλ‘λ―Έμ€ μ¬μ© κ°λ₯
const fetch = require('node-fetch'); // 1οΈβ£ node νκ²½μμ fetch μ¬μ©μ μν λͺ¨λ
const co = require('co'); // 2οΈβ£ co: μ λλ μ΄ν° κΈ°λ° λΉλκΈ° μ€νκΈ°
co(function* fetchTodo() { // 3οΈβ£ co()κ° μ λλ μ΄ν° ν¨μλ₯Ό μ€ν
const url = '<https://jsonplaceholder.typicode.com/todos/1>';
const response = yield fetch(url); // 4οΈβ£ fetch() → Promise λ°ν → coκ° resolveλ λκΉμ§ κΈ°λ€λ¦Ό
const todo = yield response.json(); // 5οΈβ£ response.json() → Promise λ°ν → coκ° resolveλ λκΉμ§ κΈ°λ€λ¦Ό
console.log(todo); // 6οΈβ£ μ΅μ’
λ°μ΄ν° μΆλ ₯
});
μ΄κ±°λ μμμ λ΄€λ μ λλ μ΄ν° ν¨μ μμ΄ async ν¨μλ‘ κ΅¬ν
1. async ν¨μ
- await ν€μλλ λ°λμ async ν¨μ λ΄λΆμμ μ¬μ©ν΄μΌ νλ€.
- async ν¨μλ async ν€μλλ₯Ό μ¬μ©ν΄ μ μνλ©° μΈμ λ νλ‘λ―Έμ€λ₯Ό λ°ννλ€.
- async ν¨μκ° λͺ μμ μΌλ‘ νλ‘λ―Έμ€λ₯Ό λ°ννμ§ μλλΌλ async ν¨μλ μ묡μ μΌλ‘ λ°νκ°μ resolve νλ νλ‘λ―Έμ€λ₯Ό λ°ννλ€.
async function foo() {
return 1;
}
// μλ λ μ½λλ κ°λ€
foo().then(console.log); // 1
Promise.resolve(1).then(console.log); // 1
→ async ν€μλλ νμ Promise κ°μ²΄λ₯Ό λ°ννλ ν¨μλ₯Ό λ§λ λ€
μ¦, ν¨μ μμμ return 1;μ²λΌ νλ²νκ² λ°νν΄λ, μ€μ λ°νκ°μ Promise.resolve(1) μ΄ λλ€
1. async ν¨μ μ μΈλ¬Έ
async function foo(n) { return n; }
foo(1).then(v => console.log(v)); // 1
- μΌλ° ν¨μ μ μΈ(function foo) μμ async ν€μλλ₯Ό λΆμΈ νν.
- νΈμΆ μ Promiseλ‘ κ°μΈμ§ κ°μ λ°ν → .then()μΌλ‘ κ²°κ³Ό μ²λ¦¬ κ°λ₯.
2. async ν¨μ ννμ
const bar = async function (n) { return n; };
bar(2).then(v => console.log(v)); // 2
- μ΄λ¦ μλ ν¨μμ asyncλ₯Ό λΆμ¬ λ³μμ ν λΉ.
- 첫 λ²μ§Έ μμμ λμμ κ°κ³ , μ΅λͺ ν¨μ ννλ‘ μ¬μ©ν μ μμ.
3. async νμ΄ν ν¨μ
const baz = async n => n;
baz(3).then(v => console.log(v)); // 3
- νμ΄ν ν¨μ λ²μ .
- ν μ€μΌ κ²½μ° {}μ returnμ μλ΅ κ°λ₯.
- async + νμ΄ν ν¨μ μ‘°ν©μ μ§§μ λΉλκΈ° μ½λ°± μμ±μ μμ£Ό μ¬μ©λ¨.
- μ: arr.map(async item => await fetch(item))
4. async λ©μλ (κ°μ²΄ 리ν°λ΄ μ)
const obj = {
async foo(n) { return n; }
};
obj.foo(4).then(v => console.log(v)); // 4
- κ°μ²΄ λ©μλμ asyncλ₯Ό λΆμΈ νν.
- κ°μ²΄μ νλ‘νΌν° fooκ° λΉλκΈ° ν¨μκ° λμ΄ Promise λ°ν.
5. async ν΄λμ€ λ©μλ
class MyClass {
async bar(n) { return n; }
}
const myClass = new MyClass();
myClass.bar(5).then(v => console.log(v)); // 5
- ν΄λμ€ λ΄λΆ λ©μλμ asyncλ₯Ό λΆμ΄λ©΄, κ·Έ λ©μλλ Promiseλ₯Ό λ°ν.
- μ£Όλ‘ λΉλκΈ° μ΄κΈ°ν, μλ² μμ², DB νΈμΆ λ±μμ μμ£Ό μ¬μ©λ¨.
λͺ¨λ Promise λ₯Ό λ°ννλ€λ μ μ λμΌ, μ°¨μ΄λ μ μΈ μμΉμ λ¬Έλ² ννμλ§ μλ€.
μ¦, asyncλ₯Ό μ΄λμ λΆμ΄λ κ·Έ ν¨μλ ‘νμ λΉλκΈ° ν¨μ’λ‘ λμ
2. await ν€μλ
await λ±μ₯ μ΄μ
Promiseλ λΉλκΈ°μ΄κΈ° λλ¬Έμ .then()μ μ¨μΌ κ²°κ³Όλ₯Ό μ»μ μ μλ€.
foo().then(v => console.log(v));
μ΄κ±Έ λ§€λ² .then()μΌλ‘ μ°λ©΄ κ°λ μ±μ΄ λλΉ μ§λ―λ‘, awaitμ΄ λ±μ₯
- await ν€μλλ νλ‘λ―Έμ€κ° settled μνκ° λ λκΉμ§ λκΈ°νλ€κ° settled μνκ° λλ©΄ νλ‘λ―Έμ€κ° resolveν μ²λ¦¬ κ²°κ³Ό λ°ννλ€.
- await ν€μλλ λ°λμ νλ‘λ―Έμ€ μμμ μ¬μ©ν΄μΌ νλ€.
μ awaitμ async ν¨μ μμμλ§ μΈ μ μλ?
- awaitμ λΉλκΈ° ν¨μμ νλ¦μ μΌμ μ€λ¨ μν€λ κΈ°λ₯μ΄κΈ° λλ¬Έ
λ§μ½ μΌλ° ν¨μμμ awaitμ μ¬μ©μ νμ©νλ©΄ λκΈ° μ½λ νλ¦μ΄ κΉ¨μ Έλ²λ¦¬κΈ° λλ¬Έμ μλ°μ€ν¬λ¦½νΈλ λ¬Έλ²μ μΌλ‘ λ§μλ
// β SyntaxError
function foo() {
const data = await fetch(...); // μΌλ° ν¨μμμ λΆκ°λ₯
}
const getGithubUserName = async id => {
const res = await fetch(`https://api.github.com/users/${id}`); // (1)
const { name } = await res.json(); // (2)
console.log(name); // Ungmo Lee
};
getGitUserName('ungmo2');
- await ν€μλλ νλ‘λ―Έμ€κ° settled μνκ° λ λκΉμ§ λκΈ°νλ€κ³ νλ€.
- (1)μ fetch ν¨μκ° μνν HTTP μμ²μ λν μλ²μ μλ΅μ΄ λμ°©ν΄μ fetch ν¨μκ° λ°νν νλ‘λ―Έμ€κ° settled μνκ° λ λκΉμ§ (1)μ λκΈ°
- νλ‘λ―Έμ€κ° settled μνκ° λλ©΄ νλ‘λ―Έμ€κ° resolveν μ²λ¦¬ κ²°κ³Όκ° res λ³μμ ν λΉ
await ν€μλλ λ€μ μ€νμ μΌμ μ€μ§ μμΌ°λ€κ° νλ‘λ―Έμ€κ° settled μνκ° λλ©΄ λ€μ μ¬κ°
β οΈ νλ‘λ―Έμ€κ° settled μνκ° λμλ€?
settled :
μ΄μ λ μ΄μ μνκ° λ°λμ§ μλ μμ
Promiseμ μν 3κ°μ§
μν μ€λͺ λ€μ λ¨κ³
| pending | λκΈ° μ€ — μμ§ κ²°κ³Ό(μ±κ³΅/μ€ν¨)κ° μ ν΄μ§μ§ μμ | → fulfilled λλ rejected λ‘ μ΄λ |
| fulfilled | λΉλκΈ° μμ μ±κ³΅(resolve νΈμΆλ¨) | settled μν |
| rejected | λΉλκΈ° μμ μ€ν¨(reject νΈμΆλ¨) | settled μν |
Promiseκ° fulfilled(μ±κ³΅) λλ rejected(μ€ν¨) μ€ μ΄λ νμͺ½μΌλ‘ κ²°μ λλ©΄ κ·Έ μμ λΆν°λ settled(νμ λ¨) μνκ° λ¨
μμ λΉλκΈ° μ²λ¦¬μ κ²°κ³Όλ₯Ό κ°μ§κ³ λ€μ λΉλκΈ° μ²λ¦¬λ₯Ό μννλ ν¨μμ μμ
async function bar(n) {
const a = await new Promise(resolve => setTimeout(() => resolve(n), 3000));
// λ λ²μ§Έ λΉλκΈ° μ²λ¦¬λ₯Ό μννλ €λ©΄ 첫 λ²μ§Έ λΉλκΈ° μ²λ¦¬ κ²°κ³Όκ° νμνλ€.
const b = await new Promise(resolve => setTimeout(() => resolve(a + 1), 2000));
// μΈ λ²μ§Έ λΉλκΈ° μ²λ¦¬λ₯Ό μννλ €λ©΄ λ λ²μ§Έ λΉλκΈ° μ²λ¦¬ κ²°κ³Όκ° νμνλ€.
const c = await new Promise(resolve => setTimeout(() => resolve(b + 1), 1000));
console.log([a,b,c]); // [ 1, 2, 3 ]
}
bar(1); // μ½ 6μ΄ μμλλ€.
3. μλ¬ μ²λ¦¬
λΉλκΈ° μ²λ¦¬λ₯Ό μν μ½λ°± ν¨ν΄μ λ¨μ μ μλ¬ μ²λ¦¬κ° κ³€λ
μλ¬λ νΈμΆμ λ°©ν₯μΌλ‘ μ ν
→ μ½ μ€νμ μλ λ°©ν₯μΌλ‘ μ ν
async function a() {
b();
}
function b() {
throw new Error('μλ¬!');
}
a();
a() → b() → Error λ°μ
bλ₯Ό νΈμΆν μͺ½μΈ a μͺ½μΌλ‘ μλ¬κ° μ νλμ΄ κ²°κ΅ μ μμμ Uncaught Error κ° μ‘ν
κ·Έλ°λ° setTimeoutμ λΉλκΈ°
try {
setTimeout(() => { throw new Error('Error!'); }, 1000);
} catch (e) {
console.error('μΊμΉν μλ¬', e);
}
κ²λ³΄κΈ°μ try...catchκ° μμΌλ μλ¬κ° μ‘ν κ² κ°μ§λ§,
μ€μ λ‘λ catchλ‘ μ λ€μ΄μ΅λλ€.
→ μ½ μ€νμ΄ λΆλ¦¬λκΈ° λλ¬Έ
- try...catchλ νμ¬ μ€ν μ€μΈ μ€ν μμμλ§ μ ν¨ν©λλ€.
- setTimeoutμ μ½λ°±μ νμ¬ μ€νμ΄ λλ ν,
- λμ€μ “μ΄λ²€νΈ 루ν”λ₯Ό ν΅ν΄ μλ‘ μ€νλλ ν¨μ
1. try λΈλ‘ μ€ν μμ
2. setTimeout λ±λ‘ (μ½λ°±μ μμ§ μ€ν μ λ¨)
3. try λΈλ‘ μ’
λ£ → catch λΈλ‘λ μ¬λΌμ§
4. 1μ΄ ν setTimeout μ½λ°±μ΄ μ€νλ¨ (μλ‘μ΄ μ€ν)
5. μ½λ°± λ΄λΆμμ Error λ°μ → μ΄λ―Έ try...catch λ²μ λ°μ
Uncaught Error: Error!
λΉλκΈ° ν¨μμ μ½λ°± ν¨μλ₯Ό νΈμΆν κ²μ λΉλκΈ° ν¨μκ° μλκΈ° λλ¬Έμ try...catch λ¬Έμ μ¬μ©ν΄ μλ¬λ₯Ό μΊμΉν μ μλ€.
- setTimeout μ체λ λΉλκΈ° ν¨μμ΄μ§λ§,
- μ½λ°±μ μ€νμν€λ 주체λ μλ°μ€ν¬λ¦½νΈ μμ§μ μ΄λ²€νΈ 루νμ΄κΈ° λλ¬Έ
μ¦, μ½λ°±μ΄ μ€νλ λλ try λΈλ‘μ λ¬Έλ§₯μ΄ μ΄λ―Έ μ¬λΌμ§ μνλΌ κ·Έ μμμ λ°μν μλ¬λ λ μ΄μ catchλ‘ μ νλμ§ λͺ»ν¨
λΉλκΈ°μ½λ°± λ΄λΆμ μλ¬λ₯Ό μ‘κ³ μΆλ€λ©΄ μ½λ°± λ΄λΆμμ μ§μ try…catch
setTimeout(() => {
try {
throw new Error('Error!');
} catch (e) {
console.error('μλ¬ μ‘μ:', e);
}
}, 1000);
