본문 바로가기

Javascript/기초부터 다시 시작

비동기 통신

콜백함수

function taskA(a, b, callback) {
	setTimeout(() => {
		const res = a + b;
		callback(res);
	}, 3000);
}

taskA(3, 4, (res) => {
	console.log("A TASK RESULT : ", res);
});
console.log("코드 끝");

 

결과

 

 

function taskA(a, b, callback) {
	setTimeout(() => {
		const res = a + b;
		callback(res);
	}, 3000);
}

function taskB(a, callback) {
	setTimeout(() => {
		const res = a * 2;
		callback(res);
	}, 1000);
}

taskA(3, 4, (res) => {
	console.log("A TASK RESULT : ", res);
});
console.log("코드 끝");

taskB(7, (res) => {
	console.log("B TASK RESULT : ", res);
});
console.log("코드 끝");

 

결과

function taskA(a, b, callback) {
	setTimeout(() => {
		const res = a + b;
		callback(res);
	}, 3000);
}

function taskB(a, callback) {
	setTimeout(() => {
		const res = a * 2;
		callback(res);
	}, 1000);
}

function taskC(a, callback) {
	setTimeout(() => {
		const res = a * -1;
		callback(res);
	}, 2000);
}

taskA(3, 4, (res) => {
	console.log("A TASK RESULT : ", res);
});
console.log("코드 끝");

taskB(7, (res) => {
	console.log("B TASK RESULT : ", res);
});
console.log("코드 끝");

taskC(14, (res) => {
	console.log("C TASK RESULT : ", res);
});
console.log("코드 끝");

 

결과

 

function taskA(a, b, callback) {
	setTimeout(() => {
		const res = a + b;
		callback(res);
	}, 3000);
}

function taskB(a, callback) {
	setTimeout(() => {
		const res = a * 2;
		callback(res);
	}, 1000);
}

function taskC(a, callback) {
	setTimeout(() => {
		const res = a * -1;
		callback(res);
	}, 2000);
}

taskA(4, 5, (a_res) => {
  console.log("A RESULT : ", a_res);
  taskB(a_res, (b_res) => {
	console.log("B RESULT : ", b_res);
	taskC(b_res, (c_res) => {
	  console.log("C RESULT : ", c_res);
    });
  });
});

 

결과

 


Promise

 

콜백함수 

function isPositive(number, resolve, reject) {
	setTimeout(() => {
		if (typeof number === "number") {
			//성공 -> resolve
			resolve(number >= 0 ? "양수" : "음수");
		} else {
			//실패 reject
			reject("주어진 값이 숫자형 값이 아닙니다");
		}
	}, 2000);
}

isPositive(
	10,
	(res) => {
		console.log("성공적으로 수행됨 : ", res);
	},
	(err) => {
		console.log("실패하였음 : ", err);
	}
);

 

결과

 

function isPositive(number, resolve, reject) {
	setTimeout(() => {
		if (typeof number === "number") {
			//성공 -> resolve
			resolve(number >= 0 ? "양수" : "음수");
		} else {
			//실패 reject
			reject("주어진 값이 숫자형 값이 아닙니다");
		}
	}, 2000);
}
function isPositiveP(number) {
	const executor = (resolve, reject) => {
		//실행자
		setTimeout(() => {
			if (typeof number === "number") {
				//성공 -> resolve
				console.log(number);
				resolve(number >= 0 ? "양수" : "음수");
			} else {
				//실패 -> reject
				reject(
					"주어진 값이 숫자형 값이 아닙니다"
				);
			}
		}, 2000);
	};

	const asyncTask = new Promise(executor);
}
isPositiveP(101);

 

결과

 

function isPositive(number, resolve, reject) {
	setTimeout(() => {
		if (typeof number === "number") {
			//성공 -> resolve
			resolve(number >= 0 ? "양수" : "음수");
		} else {
			//실패 reject
			reject("주어진 값이 숫자형 값이 아닙니다");
		}
	}, 2000);
}
function isPositiveP(number) {
	const executor = (resolve, reject) => {
		//실행자
		setTimeout(() => {
			if (typeof number === "number") {
				//성공 -> resolve
				console.log(number);
				resolve(number >= 0 ? "양수" : "음수");
			} else {
				//실패 -> reject
				reject(
					"주어진 값이 숫자형 값이 아닙니다"
				);
			}
		}, 2000);
	};

	const asyncTask = new Promise(executor);
	return asyncTask;
}

const res = isPositiveP(101);

res
	.then((res) => {
		console.log("작업 성공 :", res);
	})
	.catch((err) => {
		console.log("작업 실패 :", err);
	});

 

결과

 

 

function isPositive(number, resolve, reject) {
	setTimeout(() => {
		if (typeof number === "number") {
			//성공 -> resolve
			resolve(number >= 0 ? "양수" : "음수");
		} else {
			//실패 reject
			reject("주어진 값이 숫자형 값이 아닙니다");
		}
	}, 2000);
}
function isPositiveP(number) {
	const executor = (resolve, reject) => {
		//실행자
		setTimeout(() => {
			if (typeof number === "number") {
				//성공 -> resolve
				console.log(number);
				resolve(number >= 0 ? "양수" : "음수");
			} else {
				//실패 -> reject
				reject(
					"주어진 값이 숫자형 값이 아닙니다"
				);
			}
		}, 2000);
	};

	const asyncTask = new Promise(executor);
	return asyncTask;
}

const res = isPositiveP([]);

res
	.then((res) => {
		console.log("작업 성공 :", res);
	})
	.catch((err) => {
		console.log("작업 실패 :", err);
	});

isPositiveP에 파라미터에 배열을 넣음

 

결과

 

 

function taskA(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000);
  });
}

function taskB(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}

function taskC(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * -1;
      resolve(res);
    }, 2000);
  });
}

taskA(5, 1).then((a_res) => {
  console.log("A RESULT : ", a_res);
  taskB(a_res).then((b_res) => {
    console.log("B RESULT : ", b_res);
    taskC(b_res).then((c_res) => {
      console.log("C RESULT : ", c_res);
    });
  });
});

결과

 

기대와 달리 콜백헬이랑 비슷해짐 .then을 사용하는 방식이 이상해서임

 

코드 수정

function taskA(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000);
  });
}

function taskB(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}

function taskC(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * -1;
      resolve(res);
    }, 2000);
  });
}

taskA(5, 1)
  .then((a_res) => {
    console.log("A RESULT : ", a_res);
    return taskB(a_res);
  })
  .then((b_res) => {
    console.log("B RESULT : ", b_res);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log("C RESULT : ", c_res);
  });

 

 

 

비동기처리를 호출하는 코드와 결과를 처리하는 코드를 분리 가능

function taskA(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000);
  });
}

function taskB(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}

function taskC(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * -1;
      resolve(res);
    }, 2000);
  });
}

const bPromiseResult = taskA(5, 1).then((a_res) => {
  console.log("A RESULT : ", a_res);
  return taskB(a_res);
});

console.log("맛있는 타코야끼");
console.log("맛있는 타코야끼");
console.log("맛있는 타코야끼");
console.log("맛있는 타코야끼");

bPromiseResult
  .then((b_res) => {
    console.log("B RESULT : ", b_res);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log("C RESULT : ", c_res);
  });

async & await

function hello() {
  return "hello";
}

async function helloAsync() {
  return "hello Async";
}

console.log(hello());
console.log(helloAsync());

 

결과

async를 앞에 붙여주면 자동적으로 promise를 리턴하는 비동기처리 함수가 됨

그렇담 저렇게 안 쓰고 then을 사용할 수 있다는 소리!

 

 

then 사용하여 코드 수정

function hello() {
  return "hello";
}

async function helloAsync() {
  return "hello Async";
}

helloAsync(). then((res) => {
  console.log(res);
});

 

결과

 

async라는 키워드를 붙여준 함수의 리턴값은 비동기 작업 객체의 promise에 resolve의 결과값이 됨

 

asymc를 붙여 그 함수가 promise를 반환하도록 만드는 능력이 있음

- 비동기 함수는 promise를 리턴!

 

 

 

await

function delay(ms) {
  return new Promise((resolve) => {
    // setTimeout(() => {
    //   resolve();
    // }, ms);
    setTimeout(resolve, ms);
  });
}

async function helloAsync() {
  return delay(3000).then(() => {
    return "hello Async";
  });
}

helloAsync().then((res) => {
  console.log(res);
});

setTimeout 함수 안에 콜백함수에 resolve 호출하는 것 밖에 없다면 콜백함수 자체를 resolve로 전달해도 상관 없음

 

결과

3초뒤에 "hello Async" 출력

 

 

하지만 코드가 너무 길다,,

await 사용하여 코드 줄이기

function delay(ms) {
  return new Promise((resolve) => {
    // setTimeout(() => {
    //   resolve();
    // }, ms);
    setTimeout(resolve, ms);
  });
}

async function helloAsync() {
  await delay(3000);
  return "hello Async";
}

helloAsync().then((res) => {
  console.log(res);
});

await이 붙은 줄은 동기적으로 작동

 

 

function delay(ms) {
  return new Promise((resolve) => {
    // setTimeout(() => {
    //   resolve();
    // }, ms);
    setTimeout(resolve, ms);
  });
}

async function helloAsync() {
  await delay(3000);
  return "hello Async";
}

async function main() {
  const res = await helloAsync();
  console.log(res);
}

main();

async와 await을 활용하면 promises를 반환하는 함수를 마치 동기적인 함수를 호출한 것처럼 사용할 수 있도록 만들어줌

 

 

API & fetch

API (Application Programming Interface) - 응용프로그램 프로그래밍 인터페이스 

 

1. 웹브라우저는 서버로 데이터 요청 - Request = API 호출

2. 서버는 데이터베이스에서 원하는 데이터 검색(질의) - Query

3. 데이터베이스에서 원하는 데이터 찾기 (질의에 대한 결과) - Query Result

4. 서버가 요청받은 데이터를 웹브라우저에게 전달 - Response = API 호출

 

API를 호출한다는 것은 다른 프로그램에게 데이터를 받기 위해 말을 거는 것

 

응답을 언제 받을 지 모룸 - 그래서 비동기를 이용하는 것임

 

async function getData() {
  let rawResponse = await fetch("https://jsonplaceholder.typicode.com/posts");
  let jsonResponse = await rawResponse.json();
  console.log(jsonResponse);
}

getData();

'Javascript > 기초부터 다시 시작' 카테고리의 다른 글

프로그래머스 Lv.0  (1) 2023.04.23
spread 연산자  (0) 2023.04.03
비구조화 할당  (0) 2023.04.03
조건문 업그레이드  (0) 2023.04.02
삼항연산자  (0) 2023.03.22