π€ Chapter 7: Promiseμ async/await ꡬ문
π¦ λΉλκΈ° μ½λ°± ν¨μβ
π λκΈ°μ λΉλκΈ° APIβ
- Node.jsμμ νμΌ μμ€ν
κ³Ό κ΄λ ¨λ κΈ°λ₯μ λͺ¨μλ
fs
ν¨ν€μ§λ₯Ό μ 곡νλλ°, λκΈ° λΉλκΈ° λ²μ μΌλ‘ λλμ΄ μ 곡νλ€. μλ₯Ό λ€μ΄, λκΈ° λ²μ μΈreadFileSync
μ λΉλκΈ° λ²μ μΈreadFile
λ‘ μ 곡νλ€.
import { readFileSync, readFile } from "fs";
// λκΈ° λ°©μμΌλ‘ μ½κΈ°
const buffer: Buffer = readFileSync('./package.json');
console.log(buffer.toString());
// λΉλκΈ° λ°©μμΌλ‘ μ½κΈ°
readFile('./package.json', (error: Error, buffer: Buffer) => {
console.log(buffer.toString());
});
// Promiseμ async/await ꡬ문μ μ¬μ©ν μ
const readFilePromise = (filename: string): Promise<string> =>
new Promise<string>((resolve, reject) => {
readFile(filename, (error: Error, buffer: Buffer) => {
if(error) {
reject(error);
} else {
resolve(buffer.toString());
}
});
});
(async () => {
const content = await readFilePromise('./package.json');
console.log(content);
})();
- API ν¨μλ μΌλ° ν¨μμ λ¬λ¦¬ νλλμ€ν¬μ μ μ₯λ νμΌμ μ½λ λ± μ€νμ 물리μ μΈ μκ°μ΄ μμλλ€.
- λ°λΌμ νμΌ λ΄μ©μ λͺ¨λ μ½μ λκΉμ§ νλ‘κ·Έλ¨μ λμμ μ μ λ©μΆλ λκΈ° λ°©μμ APIμ νλ‘κ·Έλ¨μ λμμ λ©μΆμ§ μλ λμ κ²°κ³Όλ₯Ό μ½λ°± ν¨μλ‘ μ»κ² νλ λΉλκΈ° λ°©μμ APIλ₯Ό μ 곡νλ€.
- λΉλκΈ° APIμ μ½λ°± ν¨μλ₯Ό λΉλκΈ° μ½λ°± ν¨μλΌκ³ νλ€. λΉλκΈ° μ½λ°± ν¨μλ μΌλ° ν¨μμ λ¬λ¦¬ APIμ 물리μ μΈ λμ κ²°κ³Όλ₯Ό μμ νλ λͺ©μ μΌλ‘λ§ μ¬μ©νλ€.
π λ¨μΌ μ€λ λμ λΉλκΈ° APIβ
- μλ°μ€ν¬λ¦½νΈλ λ¨μΌ μ€λ λλ‘ λμνλ―λ‘ λ μ μμΌλ©΄
readFileSync
μ κ°μ λκΈ° APIλ₯Ό μ¬μ©νμ§ λ§μμΌ νλ€. - λκΈ° APIκ° μ€νλλ©΄, μ΄μ체μ λ λκΈ° APIμ μμ κ²°κ³Όλ₯Ό ν¨μμ λ°νκ°μΌλ‘ λλ €μ€μΌ νλ€. μ΄ λλ¬Έμ μ΄μ체μ λ λκΈ° APIκ° μ€νλ μ½λλ₯Ό μΌμμ μΌλ‘ λ©μΆ λ€μ, λ λ€λ₯Έ μ€λ λμμ μ€μ μμ μ μ€νν΄ μΌ€κ³Όλ₯Ό μ»μΌλ©΄ κ·ΈλμμΌ μ μ λ©μ·λ λκΈ° APIλ₯Ό μ€ννλ©΄μ κ²°κ΄κ°μ λ°ννλ€. κ·Έλ κΈ° λλ¬Έμ κ²°κ³Όλ₯Ό λ°νν λκΉμ§ μΌμμ μΌλ‘ λ©μΆλ νμμ΄ λ°μνλ€.
π μ½λ°± μ§μ₯β
- λΉλκΈ° APIλ₯Ό μ¬μ©νλ©΄ μ½λ°± ν¨μμμ λ λ€μ λ€λ₯Έ λΉλκΈ° APIλ₯Ό νΈμΆνλ μ½λλ₯Ό λ§λ€ λ μ½λκ° λ§€μ° λ³΅μ‘ν΄μ§λ€.
import { readFile } from "fs";
readFile('./package.json', (error: Error, buffer: Buffer) => {
if (error) {
throw error;
} else {
const content: string = buffer.toString();
console.log(content);
}
readFile('./tsconfig.json',(err: Error, buffer: Buffer) => {
if (error) {
throw error;
} else {
const content: string = buffer.toString();
console.log(content);
}
})
});
Promise
λ₯Ό μ¬μ©νλ©΄ μ΄λ° μ½λ°± μ§μ₯μ λΉ μ§ μ½λλ₯Ό μ’ λ λ€λ£¨κΈ° μ¬μ΄ ννμ μ½λλ‘ λ§λ€ μ μλ€.
π¦ Promise μ΄ν΄νκΈ°β
- νμ
μ€ν¬λ¦½νΈμμ
Promise
λ λ€μκ³Ό κ°μ΄ μ λ€λ¦ ν΄λμ€ ννλ‘ μ¬μ©λλ€.
const numPromise: Promise<number> = new Promise<number>(μ½λ°±ν¨μ);
const strPromise: Promise<string> = new Promise<string>(μ½λ°±ν¨μ);
const arrayPromise: Promise<number[]> = new Promise<number[]>(μ½λ²‘νμ);
- νμ
μ€ν¬λ¦½νΈ
Promise
μ μ½λ°± ν¨μλ λ€μμ²λΌresolve
μreject
ν¨μλ₯Ό 맀κ°λ³μλ‘ λ°λ ννμ΄λ€.
new Promise<T>((
resolve: (successValue: T) => void,
reject: (any) => void,
) => {
// μ½λ ꡬν
});
π resolveμ reject ν¨μβ
- λ€μμ λΉλκΈ° APIμΈ
readFile
μ νΈμΆνλ λ΄μ©μ νλ‘λ―Έμ€λ‘ ꡬνν μμ΄λ€.
import { readFile } from 'fs';
export const readFilePromise = (filename: string): Promise<string> =>
new Promise<string>((
resolve: (value: string) => void,
reject: (error: Error) => void) => {
readFile(filename, (err: Error, buffer: Buffer) => {
if(err) {
reject(err);
} else {
resolve(buffer.toString());
}
})
}
)
- λ€μ μ½λλ
readFilePromise
ν¨μκ° λ°ννλPromise
νμ κ°μ²΄μthen
,catch
,finally
λ©μλλ₯Ό λ©μλ μ²΄μΈ ννλ‘ μ¬μ©νλ€.
import { readFilePromise } from "./readFilePromise";
readFilePromise('./package.json')
.then((content: string) => {
console.log(content);
return readFilePromise('./tsconfig.json');
})
.then((content: string) => {
console.log(content);
return readFilePromise('.');
})
.catch((err: Error) => console.log('error: ', err.message))
.finally(() => console.log('νλ‘κ·Έλ¨ μ’
λ£'));
π Promise.resolveμ Promise.reject λ©μλβ
Promise.resolve(κ°)
ννλ‘ νΈμΆνλ©΄ νμ μ΄ κ°μthen
λ©μλμμ μ»μ μ μλ€.
Promise.resolve({ name: 'Jack', age: 32 })
.then(value => console.log(value)); // { name: 'Jack', age: 32 }
Promise.reject(Error νμ κ°μ²΄)
λ₯Ό νΈμΆνλ©΄ μ΄ Error νμ κ°μ²΄λ νμcatch
λ©μλμ μ½λ°± ν¨μμμ μ»μ μ μλ€.
Promise.reject(new Error('μλ¬ λ°μ'))
.catch((err: Error) => console.log('error: ', err.message)); // error: μλ¬ λ°μ
π then-체μΈβ
Promise
κ°μ²΄μthen
λ©μλλ₯Ό μ¬λ¬ λ² νΈμΆνλ μ½λ ννλ₯Όthen-체μΈ
μ΄λΌκ³ νλ€.
Promise.resolve(1)
.then((value: number) => {
console.log(value); // 1
return Promise.resolve(true);
})
.then((value: boolean) => {
console.log(value); // true
return [1, 2, 3];
})
.then((value: number[]) => {
console.log(value); // [1, 2, 3]
return { name: 'jack', age: 32 };
})
.then((value: { name: string, age: number }) => {
console.log(value); // { name: 'jack', age: 32 }
})
πPromise.all λ©μλβ
Promise.all
λ©μλλPromise
κ°μ²΄λ₯Ό λ°°μ΄ ννλ‘ λ°μ, λͺ¨λ κ°μ²΄λ₯Ό λμμΌλ‘resolve
λ κ°λ€μ λ°°μ΄λ‘ λ§λ€μ΄ μ€λ€.Promise.all
λ©μλλ μ΄λ° λ΄μ©μΌλ‘ ꡬμ±λ λ λ€λ₯ΈPromise
κ°μ²΄λ₯Ό λ°ννλ―λ‘ ν΄μλ κ°λ€μ λ°°μ΄μthen
λ©μλλ₯Ό νΈμΆν΄μ μ»λλ€.- λ§μ½, λ°°μ΄μ λ΄κΈ΄
Promise
κ°μ²΄ μ€ κ±°μ κ°μ²΄κ° λ°μνλ©΄ λ κΈ°λ€λ¦¬μ§ μκ³ ν΄λΉ κ±°μ κ°μ λ΄μPromise.reject
κ°μ²΄λ₯Ό λ°ννλ€.
const getAllResolvedResult = <T>(promises: Promise<T>[]) => Promise.all(promises);
getAllResolvedResult<any>([Promise.resolve(true), Promise.resolve('hello')])
.then(result => console.log(result)); // [true, 'hello']
getAllResolvedResult<any>([Promise.reject(new Error('error')), Promise.resolve(1)])
.then(result => console.log(result)) // νΈμΆλμ§ μλλ€.
.catch(error => console.log('error: ', error.message)); // error: error
π Promise.race λ©μλβ
Promise.race
ν΄λμ€ λ©μλλ λ°°μ΄μ λ΄κΈ΄ νλ‘λ―Έμ€ κ°μ²΄ μ€ νλλΌλresolve
λλ©΄ μ΄ κ°μ λ΄μPromise.resolve
κ°μ²΄λ₯Ό λ°ννλ€. λ§μΌ κ±°μ κ°μ΄ κ°μ₯ λ¨Όμ λ°μνλ©΄promise.reject
κ°μ²΄λ₯Ό λ°ννλ€.
Promise.race([Promise.resolve(true), Promise.resolve('hello')])
.then(value => console.log(value)); // true
Promise.race([Promise.resolve(true), Promise.reject(new Error('hello'))])
.then(value => console.log(value)) // true
.catch(error => console.log(error.message)); // νΈμΆλμ§ μλλ€
Promise.race([Promise.reject(new Error('error')), Promise.resolve(true)])
.then(value => console.log(value)) // νΈμΆλμ§ μλλ€
.catch(error => console.log(error.message)); // error
π¦ asyncμ await ꡬ문β
π async ν¨μμ λ κ°μ§ μ±μ§β
async
ν¨μ μμ μκ° λΆ μ ν¨μλ λ€μκ³Ό κ°μ μ±μ§μ κ°μ§κ³ μλ€.
- μΌλ° ν¨μμ²λΌ μ¬μ©ν μ μλ€.
Promise
κ°μ²΄λ‘ μ¬μ©ν μ μλ€.
π async ν¨μκ° λ°ννλ κ°μ μλ―Έβ
async
ν¨μλ κ°μ λ°νν μ μλ€. μ΄λ λ°νκ°μPromise
ννλ‘ λ³νλλ―λ‘ λ€μμ²λΌthen
λ©μλλ₯Ό νΈμΆν΄async
ν¨μμ λ°νκ°μ μ»μ΄μΌ νλ€.
const asyncReturn = async() => {
return [1, 2, 3];
}
asyncReturn()
.then(value => console.log(value)); // [1, 2, 3]
π async ν¨μμ μμΈ μ²λ¦¬β
const asyncException = async () => {
throw new Error('error');
}
asyncException()
.catch(err => console.log('error: ', err.message)); // error: error
π async ν¨μμ Promise.allβ
import { readFilePromise } from "./readFilePromise"
const readFilesAll = async (fileNames: string[]) => {
return await Promise.all(
fileNames.map(fileNames => readFilePromise(fileNames))
);
}
readFilesAll(['./package.json', './tsconfig.json'])
.then(([packageJson, tsConfigJson]: string[]) => {
console.log(packageJson);
console.log(tsConfigJson);
})
.catch(err => console.log(err))