λͺ¨λ μλ°μ€ν¬λ¦½νΈ Deep Dive λμμ 46μ₯ μ λλ μ΄ν°μ async/awaitλ₯Ό μ 리νμμ΅λλ€.
μ½λ λΈλ‘μ μ€νμ μΌμ μ€μ§νλ€κ° νμν μμ μ μ¬κ°ν μ μλ νΉμν ν¨μλ€.
function*
ν€μλλ‘ μ μΈνλ€. κ·Έλ¦¬κ³ νλ μ΄μμ yield ννμ
μ ν¬ν¨νλ€.
// μ λλ μ΄ν° ν¨μ μ μΈλ¬Έ
function* genDecFunc() {
yield 1;
}
// μ λλ μ΄ν° ν¨μ ννμ
const genExpFunc = function* () {
yield 1;
}
// μ λλ μ΄ν° λ©μλ
const obj = {
* genObjMethod() {
yield 1;
}
}
// μ λλ μ΄ν° ν΄λμ€ λ©μλ
class MyClass {
* genClsMethod() {
yield 1;
}
}
const genArrowFunc = * () => {
yield 1;
}// syntaxError: Unexpected token '*'
function* genFunc() {
yield 1;
}
new genFunc(); // TypeError: genFunc is not a constructor
μ λλ μ΄ν° ν¨μλ₯Ό νΈμΆνλ©΄ μΌλ° ν¨μμ²λΌ ν¨μ μ½λ λΈλ‘μ μ€ννλ κ²μ΄ μλλΌ μ λλ μ΄ν° κ°μ²΄λ₯Ό μμ±ν΄ λ°ννλ€. μ λλ μ΄ν° ν¨μκ° λ°νν μ λλ μ΄ν° κ°μ²΄λ μ΄ν°λ¬λΈμ΄λ©΄μ λμμ μ΄ν°λ μ΄ν°λ€.
μ λλ μ΄ν° κ°μ²΄λ Symbol.iterator
λ©μλλ₯Ό μμλ°λ μ΄ν°λ¬λΈμ΄λ©΄μ value, done νλ‘νΌν°λ₯Ό κ°λ μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄λ₯Ό λ°ννλ next λ©μλλ₯Ό μμ νλ μ΄ν°λ μ΄ν°λ€.
// μ λλ μ΄ν° ν¨μ
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 λ©μλλ₯Ό κ°λλ€.
// 46-06
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: return}
console.log(generator.throw('Error')); // {value: undefined, done: true}
yield ν€μλλ μ λλ μ΄ν° ν¨μμ μ€νμ μΌμ μ€μ§ μν€κ±°λ yield ν€μλ λ€μ μ€λ ννμμ νκ° κ²°κ³Όλ₯Ό μ λλ μ΄ν° ν¨μ νΈμΆμμκ² λ°ννλ€.
function* genFunc() {
const x = yield 1;
const y = yield (x + 10);
// μΌλ°μ μΌλ‘ μ λλ μ΄ν°μ λ°νκ°μ μλ―Έκ° μλ€.
// λ°λΌμ μ λλ μ΄ν°μμλ κ°μ λ°νν νμκ° μκ³ returnμ μ’
λ£μ μλ―Έλ‘λ§ μ¬μ©ν΄μΌ νλ€.
return x + y;
}
const generator = genFunc(0);
let res = generator.next();
console.log(res); // {value: 1, done: false}
res = generator.next(10);
console.log(res); // {value: 20, done: true}
res = generator.next(20);
console.log(res); // {value: 30, done: true}
const infiniteFibonacci = (function () {
let [pre, cur] = [0, 1];
return {
[Symbol.iterator]() { return this; },
next() {
[pre, cur] = [cur, pre + cur];
// 무ν μ΄ν°λ¬λΈμ΄λ―λ‘ done νλ‘νΌν° μλ΅
return { value: cur };
}
}
}());
for (const num of infiniteFibonacci) {
if (num > 10000) break;
console.log(num); // 1 2 3 5 8 --
}
μμ ν¨μλ₯Ό μλμ²λΌ μ¬μ©ν μ μλ€.
const infiniteFibonacci = (function* () {
let [pre, cur] = [0, 1];
while(true) {
[pre, cur] = [cur, pre + cur];
yield cur;
}
}());
μ λλ μ΄ν° ν¨μλ νλ‘λ―Έμ€λ₯Ό μ¬μ©ν λΉλκΈ° μ²λ¦¬λ₯Ό λκΈ° μ²λ¦¬ μ²λΌ ꡬνν μ μλ€.
const async = generatorFunc => {
const generator = generatorFunc(); // 2
const onResolved = arg => {
const result = generator.next(arg); // 5
return result.done ? result.value : result.value.then(res -> onResolved(res));
}
return onResolved;
}
ECMAScript 2017(ES8)μμλ μ λλ μ΄ν°λ³΄λ€ κ°λ¨νκ³ κ°λ
μ± μ’κ² λΉλκΈ° μ²λ¦¬λ₯Ό λκΈ° μ²λ¦¬μ²λΌ λμν μ μλ async/await
κ° λμ
λμλ€.
νλ‘λ―Έμ€ κΈ°λ°μΌλ‘ λμνλ©° νλ‘λ―Έμ€μ νμ μ²λ¦¬ λ©μλ μμ΄ λ§μΉ λκΈ° μ²λ¦¬μ²λΌ νλ‘λ―Έμ€κ° μ²λ¦¬ κ²°κ³Όλ₯Ό λ°ννλλ‘ κ΅¬νν μ μλ€.
async function foo(n) { return n; }
foo(1).then(v => console.log(v)); // 1
const obj = {
async foo(n) { return n; }
}
obj.foo(4).then(v => console.log(v)); // 4
ν΄λμ€μ contructor λ©μλλ async λ©μλκ° λ μ μλ€. ν΄λμ€μ constructor λ©μλλ μΈμ€ν΄μ€λ₯Ό λ°νν΄μΌ νμ§λ§ async ν¨μλ μΈμ λ νλ‘λ―Έμ€λ₯Ό λ°νν΄μΌ νλ€.
await ν€μλλ νλ‘λ―Έμ€κ° settled μν(λΉλκΈ° μ²λ¦¬κ° μνλ μν)
κ° λ λκΉμ§ λκΈ°νλ€κ° settled μνκ° λλ©΄ resloveν μ²λ¦¬ κ²°κ³Όλ₯Ό λ°ννλ€. λͺ¨λ νλ‘λ―Έμ€μ await ν€μλλ₯Ό μ¬μ©νλ κ²μ μ£Όμν΄μΌνλ€.
λΉλκΈ° μ²λ¦¬λ₯Ό μν μ½λ°± ν¨ν΄μ λ¨μ μ€ κ°μ₯ μ¬κ°ν κ²μ μλ¬ μ²λ¦¬κ° κ³€λνλ€λ κ²μ΄λ€. μ¦, μ½ μ€νμ μλλ°©ν₯(μ€ν μ€μΈ 컨ν μ€νΈκ° νΈμλκΈ° μ§μ μ νΈμλ μ€ν 컨ν μ€νΈ λ°©ν₯)μΌλ‘ μ νλλ€.
νμ§λ§ λΉλκΈ° ν¨μμ μ½λ°±ν¨μλ₯Ό νΈμΆν κ²μ λΉλκΈ° ν¨μκ° μλκΈ° λλ¬Έμ try ... catch λ¬Έμ μ¬μ©ν΄ μλ¬λ₯Ό μΊμΉν μ μλ€. νμ§λ§ async/await
μμ μλ¬ μ²λ¦¬λ try ... catch λ¬Έμ μ¬μ©ν μ μλ€. μ½λ°±
async ν¨μ λ΄μμ catch λ¬Έμ μ¬μ©ν΄μ μλ¬ μ²λ¦¬λ₯Ό νμ§ μμΌλ©΄ async ν¨μλ λ°μν μλ¬λ₯Ό rejectνλ νλ‘λ―Έμ€λ₯Ό λ°ννλ€.
Ref
- μ΄μ λͺ¨ μ , βλͺ¨λ μλ°μ€ν¬λ¦½νΈ Deep Diveβ, μν€λΆμ€