Search
Duplicate
moon
sun

3.함수와 객체

목차(클릭하세요)
💡

1. JS만의 함수 특징

1-1. 함수와 호이스팅

•
호이스팅(Hoisting)은 변수와 함수 선언이 해당 스코프의 최상단으로 "끌어올려지는" JavaScript의 독특한 동작

함수 선언문 호이스팅

// 함수 호출이 선언보다 먼저 와도 동작함 sayHello(); // "안녕하세요!" - 정상 동작 function sayHello() { console.log("안녕하세요!"); }
JavaScript
복사
•
이게 왜 될까?
◦
자바스크립트는 코드를 실행하기전 준비단계를 거치는데, 이 때 중첩함수가 아닌 함수들은 모두 찾아 미리 생성해두는 자바스크립트의 괴랄한 특성때문 인듯
•
무슨 장점이라도?
◦
함수 선언의 위치를 강제하지 않아 더 유연한 프로그래밍이 가능해짐

1-2.함수 표현식

•
함수를 변수에 할당하는 방식으로, 함수를 값처럼 다룰 수 있음
// 함수 선언문 function declaration() { return "선언문"; } // 함수 표현식 const expression = function() { return "표현식"; }; // 명명된 함수 표현식 const namedExpression = function myFunc() { return "명명된 표현식"; };
JavaScript
복사
[함수표현식에서 무슨 차이?]
•
함수 표현식 = 기본적으로 익명 함수를 변수/상수에 할당하는 방식.
•
명명된 함수 표현식 = 이름이 붙은 함수 표현식 (주로 디버깅 편의를 위해 사용).

1-3.화살표 함수

•
ES6에서 도입된 간결한 함수 표현 방식
•
익명함수를 매우 간결하게 작성할 때 사용
•
➡️ 일종의 함수표현식의 단축문법
[사용법] let funcA = (매개변수) => 반환값;
JavaScript
복사
// 기본 화살표 함수 const add = (a, b) => { return a + b; }; // 한 줄 함수 - return 생략 가능 const multiply = (a, b) => a * b; // 매개변수가 하나일 때 - 괄호 생략 가능 const square = x => x * x; // 매개변수가 없을 때는 괄호 생략 불가능 const sayHello = () => "안녕하세요!";
JavaScript
복사
[화살표 함수 사용Tip]
•
화살표 함수(()=>{})를 변수에 담을 때는 let보다 const를 더 자주 사용
•
이유: 대부분의 경우 함수 정의가 한 번 정해지면 바뀌지 않으므로 const가 적합
const add = (a, b) => a + b; // 안전 // add = 100; ❌ 에러 발생
JavaScript
복사

1-3.함수 연습문제

//코드샌드박스에서 출력을 위한 기본 코드 import "./styles.css"; // HTML 먼저 생성 document.getElementById("app").innerHTML = ` <h1 id="title">🎮 게임 함수 마스터</h1> <p id="change">빈칸(???)을 채워서 게임을 완성하세요!</p> <div id="test" style="white-space: pre-line;"></div> `; let result = ""; // === 1. 게임 초기화 (함수 호이스팅) === result += "=== 1. 게임 초기화 ===\n"; // 사용자 이름 입력받기 ??? playerName = prompt("플레이어 이름을 입력하세요:") ??? "익명"; // 값이 변할 수 있는 변수 키워드, 기본값을 제공하는 연산자 // 함수 선언 전에 호출 가능! (호이스팅) let gameStart = startGame(playerName); result += gameStart + "\n"; ??? startGame(name) { // 호이스팅이 가능한 함수 선언 방식 return `${name}님의 모험이 시작됩니다!`; } result += "\n"; // === 2. 게임 플레이 (함수 표현식) === result += "=== 2. 게임 플레이 ===\n"; // 몬스터 전투 함수 (함수 표현식) ??? battleMonster = function(playerLevel, monsterLevel) { // 변하지 않는 변수에 함수를 저장 ??? damage = playerLevel * 10 - monsterLevel * 5; // 함수 내부에서 계산값을 저장할 변수 return damage > 0 ? "승리!" : "패배..."; }; // 아이템 획득 함수 (화살표 함수) ??? getItem = (itemName) ??? `${itemName} 획득!`; // 짧은 함수를 간단하게 쓰는 방법, 화살표 기호 let battle1 = battleMonster(5, 3); let battle2 = battleMonster(2, 4); let item = getItem("마법검"); result += `전투 1: ${battle1}\n`; result += `전투 2: ${battle2}\n`; result += `아이템: ${item}\n\n`; // === 3. 게임 결과 (화살표 함수 활용) === result += "=== 3. 게임 결과 ===\n"; let scores = [100, 250, 180, 320, 90]; // 고득점만 필터링 (화살표 함수) ??? highScores = scores.???(score ??? score >= 200); // 조건에 맞는 요소만 걸러내는 배열 메서드 // 점수 합계 계산 (화살표 함수) ??? total = scores.???(???sum, score) ??? sum + score, 0); // 배열을 하나의 값으로 축약하는 메서드, 누적값 매개변수 // 최종 등급 계산 (화살표 함수) ??? getGrade = (score) ??? score >= 300 ??? "S" ??? score >= 200 ??? "A" ??? "B"; // 조건에 따라 값을 선택하는 연산자 let finalGrade = getGrade(total); result += `${playerName}님의 결과:\n`; result += `고득점: ${highScores.join(", ")}\n`; result += `총점: ${total}\n`; result += `최종 등급: ${finalGrade}\n`; document.getElementById("test").textContent = result;
JavaScript
복사

2. 객체와 배열

2-1. 객체 생성과 프로퍼티(with 리터럴??)

•
객체는 키(key)와 값(value)의 쌍으로 데이터를 저장하는 JavaScript의 핵심 데이터 구조
// 기본 객체 생성 const student = { name: "양파고", age: 17, school: "한국고등학교", isStudent: true }; // 중첩 객체 const player = { name: "철수", stats: { level: 15, hp: 100, mp: 50 }, inventory: ["검", "방패", "포션"] };
JavaScript
복사
[리터럴이란?]
•
literal = “값 그 자체를 코드에 직접 적어 표현한 것”
•
즉, 프로그래머가 코드에 직접 써넣은 값을 뜻함
•
예시
◦
숫자 리터럴: 10, 3.14
◦
문자열 리터럴: "hello", 'world'
◦
불리언 리터럴: true, false
•
객체 리터럴이란?
◦
중괄호 {}를 사용해 객체를 직접 정의하는 문법
•
객체 리터럴과 반대되는 개념이 표현식이라 생각하면 편함
◦
new Object() → 객체를 만드는 표현식(expression)
◦
{ name: "A" } → 직접 속성과 값을 적어 객체를 만드는 리터럴(literal)
구분
코드 예시
설명
사용 빈도
리터럴
const obj = { name: "민수", age: 17 };
직접 {} 안에 값 써서 객체 생성
★★★★★
표현식 - 생성자 함수 호출
new Student("민수", 17)
함수 정의 후 new로 호출
★★★☆☆
표현식 - new Object()
new Object()
내장 생성자 호출 후 속성 추가
★☆☆☆☆
[생성자 함수로 객체생성하기]
function Student(name, age) { this.name = name; this.age = age; this.study = function() { return `${this.name}이(가) 공부 중입니다.`; }; } const student1 = new Student("민수", 17);
JavaScript
복사

2-2.객체 프로퍼티 다루기

[프로퍼티란?]
•
객체(Object)는 키(key)와 값(value)의 쌍으로 이루어짐.
•
이때 키를 프로퍼티 이름(property name), 값을 프로퍼티 값(property value)라고 부름.
•
즉, 프로퍼티 = 키 + 값 쌍 전체를 가리킴
1.
프로퍼티의 특징
•
동적 추가: 언제든지 새로운 프로퍼티 추가 가능
•
다양한 타입: 문자열, 숫자, 불리언, 함수, 객체 등 모든 타입 저장 가능
•
메서드: 객체 내부의 함수를 메서드라고 함
2.
프로퍼티의 접근방법은 크게 2가지: 점 표기법, 대괄호 표기법
•
점표기법
const user = { name: "양파고", age: 17, email: "yangphago@example.com" }; console.log(user.name); // "양파고" console.log(user.age); // 17
JavaScript
복사
•
대괄호 표기법
console.log(user["name"]); // "양파고" console.log(user["age"]); // 17 // 변수를 키로 사용 가능 const key = "email"; console.log(user[key]); // "yangphago@example.com" // 공백이나 특수문자가 있는 키 const game = { "player name": "철수", "high-score": 1500 }; console.log(game["player name"]); // "철수"
JavaScript
복사
3.
프로퍼티 추가&수정하기
const car = { brand: "현대", model: "아반떼" }; // 프로퍼티 추가 car.year = 2023; car["color"] = "흰색"; // 프로퍼티 수정 car.model = "소나타";
JavaScript
복사
4.
프로퍼티 삭제하기
delete car.color; console.log(car.color); // undefined
JavaScript
복사

2-3.배열과 배열 인덱스

•
배열은 순서가 있는 데이터의 집합으로, 인덱스를 통해 요소에 접근
•
자바스크립트의 배열은 단순히 순서를 가진 특별한 객체
◦
인덱스(0, 1, 2, …)가 키처럼 작동하고,
◦
배열 객체 안에는 length 같은 프로퍼티와 push, pop 같은 메서드가 기본 내장돼 있음
const games = ["롤토체스", "리그오브레전드"]; // 끝에 추가/제거 games.push("발로란트"); // ["롤토체스", "리그오브레전드", "발로란트"] games.pop(); // "발로란트" 제거 // 앞에 추가/제거 games.unshift("오버워치"); // ["오버워치", "롤토체스", "리그오브레전드"] games.shift(); // "오버워치" 제거
JavaScript
복사

2-4.date객체와 날짜

•
Date 객체는 날짜와 시간을 다루는 JavaScript의 내장 객체
const now = new Date(); // 기본 문자열 변환 console.log(now.toString()); // 전체 날짜 시간 console.log(now.toDateString()); // 날짜만 console.log(now.toTimeString()); // 시간만 // 로케일 형식 console.log(now.toLocaleDateString("ko-KR")); // "2025. 3. 7." console.log(now.toLocaleTimeString("ko-KR")); // "오후 2:30:45" //date함수의 사용법 function formatDate(date) { // 1. 연도(yyyy) 추출 const year = date.getFullYear(); // 2. 월(mm) 추출 → getMonth()는 0~11을 반환하므로 +1 // padStart(2, '0')로 두 자리 맞추기 (예: 3 → 03) const month = String(date.getMonth() + 1).padStart(2, '0'); // 3. 일(dd) 추출 → padStart로 두 자리 맞춤 const day = String(date.getDate()).padStart(2, '0'); // 4. yyyy-mm-dd 형식의 문자열로 반환 return `${year}-${month}-${day}`; }
JavaScript
복사

2-5.연습문제

객체 생성:
•
const aespa = {}
프로퍼티 접근:
•
점 표기법: aespa.groupName
•
대괄호 표기법: aespa["hit2022"]
배열 메서드:
•
filter(), map(), reduce(), length
Date 객체:
•
new Date(), getFullYear(), getMonth(), getDate()
//코드샌드박스에서 출력을 위한 기본 코드 import "./styles.css"; // HTML 먼저 생성 document.getElementById("app").innerHTML = ` <h1 id="title">🎵 aespa 히트곡 관리 시스템</h1> <p id="change">빈칸(???)을 채워서 aespa 정보 시스템을 완성하세요!</p> <div id="test" style="white-space: pre-line;"></div> `; let result = ""; // === 1. 객체 리터럴로 aespa 기본 정보 생성 === result += "=== 1. aespa 기본 정보 ===\n"; ??? aespa = { // 변경되지 않는 객체를 선언할 때 사용하는 키워드 groupName: "aespa", debutDate: new Date("2020-11-17"), company: "SM Entertainment", members: ["카리나", "지젤", "윈터", "닝닝"], }; result += `그룹명: ${aespa.???}\n`; // 객체의 속성에 접근하는 방법 중 하나 result += `소속사: ${aespa.???}\n\n`; // 위와 같은 방식으로 접근 // === 2. 히트곡 프로퍼티 추가 (점 표기법) === result += "=== 2. 히트곡 추가 (점 표기법) ===\n"; // 점 표기법으로 히트곡 추가 aespa.??? = "Black Mamba"; // 새로운 속성 이름을 정해보세요 aespa.??? = []; // 여러 곡을 담을 수 있는 데이터 구조 aespa.hit.???("Next Level"); // 배열에 요소를 추가하는 메서드 aespa.hit.???("Savage"); // 같은 메서드를 사용 aespa.hit.???("위 플래쉬"); // 계속 같은 메서드 result += `데뷔곡: ${aespa.debut_song}\n`; result += `히트곡 리스트: ${aespa.hit}\n`; // === 3. 추가 정보 (대괄호 표기법) === result += "\n=== 3. 추가 정보 (대괄호 표기법) ===\n"; // 대괄호 표기법으로 정보 추가 aespa["???"] = aespa.members.???; // 앨범 수와 관련된 속성명, 배열의 크기를 알 수 있는 속성 result += `발매 앨범의 갯수: ${aespa.total_albums}\n\n`; // === 4. 인기 멤버 순서에 따라 배열로 변환 === result += "=== 4. 인기멤버 배열 관리 ===\n"; // 인기순으로 멤버 재배열 ??? superstar_number = [ // 변경되지 않을 배열 선언 aespa.members[???], // 첫 번째 멤버 aespa.members[???], // 세 번째 멤버 aespa.members[???], // 네 번째 멤버 aespa.members[???], // 두 번째 멤버 ]; // 가장 인기 있는 멤버 (첫 번째) ??? mostPopular = superstar_number[???]; // 변경되지 않을 변수, 첫 번째 요소 result += `최고의 멤버: ${mostPopular}\n\n`; // === 5. Date 객체를 활용한 기념일 계산 === result += "=== 5. 데뷔 기념일 계산 ===\n"; ??? today = new Date(); // 오늘 날짜를 담을 변수 ??? debutYear = aespa.debutDate.???(); // 연도를 가져오는 메서드 ??? currentYear = today.???(); // 현재 연도를 가져오는 메서드 ??? yearsActive = currentYear - debutYear; // 활동 기간 계산 // 올해 데뷔 기념일 ??? thisYearAnniversary = new Date( // 올해 기념일 날짜 객체 currentYear, aespa.debutDate.???(), // 월을 가져오는 메서드 aespa.debutDate.???() // 일을 가져오는 메서드 ); // 기념일까지 남은 일수 ??? daysUntilAnniversary = Math.ceil( // 값이 변경될 수 있는 변수 (thisYearAnniversary - today) / (1000 * 60 * 60 * 24) ); // 기념일이 지났다면 내년 기념일 계산 if (daysUntilAnniversary < 0) { thisYearAnniversary.???(currentYear + 1); // 연도를 설정하는 메서드 daysUntilAnniversary = Math.ceil( (thisYearAnniversary - today) / (1000 * 60 * 60 * 24) ); } result += `데뷔: ${debutYear}년\n`; result += `활동 기간: ${yearsActive}년\n`; result += `다음 기념일까지: ${daysUntilAnniversary}일\n\n`; document.getElementById("test").textContent = result;
JavaScript
복사

3. 비동기 처리

✅ 파이썬과 달리 JS에서 비동기 처리가 중요한 이유?
→ fetch() 같은 HTTP 요청은 시간이 오래 걸리므로 비동기로 처리해야 UI가 멈추지 않음.
•
동기(Synchronous): 작업이 순서대로 하나씩 완료되어야 다음 작업을 진행
•
비동기(Asynchronous): 작업을 시작하고 완료를 기다리지 않고 다음 작업을 바로 진행
구분
동기(Sync)
비동기(Async)
실행 흐름
한 줄 끝나야 다음 줄 실행
오래 걸리는 작업은 백그라운드로 넘기고, 나머지 코드 먼저 실행
장점
코드 이해가 단순
UI 멈춤 방지, 효율적 리소스 활용
예시
alert("hi")
fetch(), setTimeout()

3-1. 동기와 비동기

✅ 은행창구는 동기 처리일까? 비동기 처리일까?
은행창구 = 동기 처리
•
한 사람의 업무가 끝나야 다음 손님이 처리 가능
✅ 까페운영은 동기 처리일까? 비동기 처리일까?
카페 = 비동기 처리
•
주문받고 나서 음료가 나올 때까지 기다리는 동안, 다른 손님의 주문도 처리 가능

3-2.비동기함수의 실제 사용법(초급)

✅ setTimeout을 이용한 비동기 처리
1.
자바스크립트는 setTimeout 메서드를 이용해 비동기적 처리 가능
console.log("주문 접수"); setTimeout(() => { console.log("커피 준비 완료 ☕"); }, 2000); // 2초 뒤 실행 console.log("다른 손님 주문 받는 중...");
JavaScript
복사
2.
조금 더 복잡한 형태의 setTimeout 이용
function processOrder() { console.log("주문 접수"); setTimeout(() => { console.log("재료 준비 완료"); setTimeout(() => { console.log("조리 완료"); setTimeout(() => { console.log("서빙 완료"); }, 2000); }, 3000); }, 1000); } processOrder()
JavaScript
복사

3-2.비동기함수의 실제 사용법(고급)

✅ 프로미스 객체를 이용한 비동기 처리
1.
3가지 상태: 대기, 성공, 실패
•
대기(Pending): 아직 결과가 나오지 않음
•
성공(Fulfilled): 작업이 성공적으로 완료됨
•
실패(Rejected): 작업이 실패함
2.
실행함수가 제공받는 2개의 매개변수: resolve, reject
•
resolve: 작업 성공 시 호출하는 함수
•
reject: 작업 실패 시 호출하는 함수
•
Promise를 만들 때 resolve만 쓰고 reject는 생략하는 게 가능
•
개발자가 가독성을 위해 이름을 줄일 수도 있음 →
•
resolve → res, reject → rej
const myPromise = new Promise((resolve, reject) => { // resolve: 성공했을 때 호출하는 함수 // reject: 실패했을 때 호출하는 함수 }); const myPromise = new Promise((res, rej) => { const num = Math.random(); // 0~1 사이 난수 if (num > 0.5) { res(`✅ 성공! 난수=${num}`); } else { rej(`❌ 실패! 난수=${num}`); } }); myPromise .then(msg => console.log("성공:", msg)) .catch(err => console.log("실패:", err));
JavaScript
복사
3.
프로미스 객체를 활용한 예시
// Promise 생성 function fetchUserData(userId) { return new Promise((resolve, reject) => { // 실제로는 서버 요청이지만 시뮬레이션 setTimeout(() => { if (userId > 0) { resolve({ id: userId, name: "양파고", email: "yangphago@example.com" }); } else { reject(new Error("유효하지 않은 사용자 ID")); } }, 1000); }); } // Promise 사용 fetchUserData(123) .then(userData => { console.log("사용자 정보:", userData); }) .catch(error => { console.log("오류 발생:", error.message); });
JavaScript
복사
[참고] settimeout메서드를 쓰는 것과 프로미스 객체를 사용하는 것의 차이?
1.
setTimeout 메서드
•
타이머 기반 비동기 처리
•
일정 시간이 지난 후 특정 코드를 실행하는 용도
•
단순한 이벤트 지연/예약 실행에 적합
•
콜백(callback) 방식으로 동작
2.
Promise 객체
•
Promise는 비동기 작업의 완료(성공) 또는 실패를 나타내는 객체로, 그 결과값을 나중에 사용할 수 있게 해줌
•
네트워크 요청, 파일 읽기/쓰기 같은 결과가 나중에 도착하는 작업을 처리할 때 사용
•
세 가지 상태(Pending → Fulfilled/Rejected)를 가짐
•
then, catch, finally 체이닝 가능 → 가독성 좋고 에러 처리 쉬움
◦
.then() → 작업 성공 시 실행할 콜백 등록
◦
.catch() → 작업 실패 시 실행할 콜백 등록
◦
.finally() → 성공/실패와 관계없이 마지막에 실행할 콜백 등록
[JS의 콜백함수?]
💡
매개변수로 함수 객체를 전달해서 호출 함수 내에서 매개변수 함수를 실행하는 것 ➡️ 콜백 함수란 파라미터로 일반적인 변수나 값을 전달하는 것이 아닌 함수 자체를 전달하는 것 어차피 매개변수에 함수를 전달해 일회용으로 사용하기 때문에 굳이 함수의 이름을 명시할 필요가 없어 보통 콜백 함수 형태로 함수를 넘겨줄때 함수의 이름이 없는 '익명 함수' 형태로 넣어주게 됨
function sayHello(name, callback) { const words = '안녕하세요 내 이름은 ' + name + ' 입니다.'; callback(words); // 매개변수의 함수(콜백 함수) 호출 } sayHello("양파고", function printing(name) { console.log(name); // 안녕하세요 내 이름은 인파 입니다. });
JavaScript
복사
•
화살표 함수모양의 콜백함수
function sayHello(callback) { let name = "phago"; callback(name); // 콜백 함수 호출 } // 익명 화살표 콜백 함수 sayHello((name) => { console.log("Hello, " + name); }); // Hello, Alice
JavaScript
복사
3.
체이닝 방식의 비동기 처리
⚠️[체이닝?]
메서드를 연속적으로 연결해서 호출하는 개념, 체이닝은 약간의 순차 실행 느낌
const order = new Promise((resolve, reject) => { const stock = true; if (stock) resolve("커피 준비 완료 ☕"); else reject("재고 없음 ❌"); }); order .then(msg => { console.log("성공:", msg); return "손님께 전달 완료 ✅"; // 다음 then으로 값 전달 }) .then(nextMsg => { console.log(nextMsg); }) .catch(err => { console.log("실패:", err); }) .finally(() => { console.log("작업 종료 🚪"); });
JavaScript
복사
4.
병렬처리 방식의 비동기처리
// 각각의 독립적인 작업들을 별도의 Promise로 분리 const checkStock = new Promise((resolve, reject) => { const stock = true; if (stock) resolve("재고 확인 완료 ✅"); else reject("재고 없음 ❌"); }); const prepareCoffee = new Promise((resolve) => { setTimeout(() => resolve("커피 준비 완료 ☕"), 1000); }); const preparePackaging = new Promise((resolve) => { setTimeout(() => resolve("포장 준비 완료 📦"), 800); }); const notifyCustomer = new Promise((resolve) => { setTimeout(() => resolve("손님 호출 완료 📢"), 500); }); // Promise.all로 병렬 처리 Promise.all([checkStock, prepareCoffee, preparePackaging, notifyCustomer]) .then(results => { console.log("모든 작업 완료:"); results.forEach(result => console.log(result)); console.log("주문 처리 완료 🎉"); }) .catch(err => { console.log("실패:", err); }) .finally(() => { console.log("작업 종료 🚪"); });
JavaScript
복사
[어려움]
•
체이닝 = 비동기 순차 실행
•
병렬 = 비동기 동시 실행
👉 즉, 둘 다 비동기이지만,
•
체이닝은 "비동기 + 한 줄씩 기다리며 처리"
•
병렬은 "비동기 + 여러 줄을 동시에 실행"

3-4.연습문제

[중요개념 돌아보기]
1.
resolve (Promise 성공 처리)
2.
task (타이머 함수)
3.
await (비동기 작업 기다리기)
4.
Promise.all (여러 비동기 작업을 동시에 처리)
5.
async (비동기 함수 선언)
// 기본 셋업 import "./styles.css"; document.getElementById("app").innerHTML = ` <h1>🍽️ 저녁식사 준비 - 비동기 실습</h1> <div id="test" style="white-space: pre-line;"></div> `; // ??? 문자열을 받아 특정 영역에 출력하고 줄바꿈("\n")을 추가하는 함수 function write(msg) { document.getElementById("test").textContent += msg + "\n"; } // 공통 타이머 작업 (ms 뒤 ??? 호출) // 힌트: 일정 시간이 지난 뒤 Promise를 성공 상태로 바꿔주는 함수 function task(taskName, ms) { return new Promise(function (????) { setTimeout(function () { ????(taskName); // 일정 시간 뒤 작업 이름 반환 }, ms); }); } // 개별 작업 실행 + 시간 측정/출력 async function doTask(taskName, ms) { const s = performance.now(); await ????(taskName, ms); // 힌트: 위에서 만든 "타이머 함수" 호출 write(`${taskName} 성공 (${((performance.now() - s) / 1000).toFixed(2)}s)`); } // 시간 상수 const T_CHICKEN = 5000; const T_SALAD = 3000; const T_TABLE = 2000; // 1) 체이닝(순차) // ??? 키워드를 사용해 작업을 순서대로 기다리며 실행 async function runChaining() { write("=== 체이닝 (순차 실행) ==="); const t0 = performance.now(); await ????("치킨", T_CHICKEN); await ????("샐러드", T_SALAD); await ????("상차리기", T_TABLE); write( `총 실제 소요 시간: ${((performance.now() - t0) / 1000).toFixed(2)}s\n` ); } // 2) 병렬(동시) // 여러 비동기 작업을 동시에 실행하려면 ??? 메서드 사용 async function runParallel() { write("=== 병렬 (동시 실행) ==="); const t0 = performance.now(); await ????.????([ doTask("치킨", T_CHICKEN), doTask("샐러드", T_SALAD), doTask("상차리기", T_TABLE), ]); write( `총 실제 소요 시간: ${((performance.now() - t0) / 1000).toFixed(2)}s\n` ); } // 실행 (순서 보장) // ??? 함수 표현식 → 비동기 실행 흐름 제어 가능 (???? () => { await runChaining(); await runParallel(); })();
JavaScript
복사