ν‹°μŠ€ν† λ¦¬ λ·°

javascript/λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ

9. generators

λŒ•λŒ•μ΄λ°œπŸΎ 2019. 1. 22. 17:36




μ œλ„ˆλ ˆμ΄ν„°λž€?

: μ΄ν„°λ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•΄ μžμ‹ μ˜ 싀행을 μ œμ–΄ν•˜λŠ” ν•¨μˆ˜. 일반적인 ν•¨μˆ˜λŠ” 호좜되면 κ·Έ ν•¨μˆ˜κ°€ μ’…λ£Œλ  λ•ŒκΉŒμ§€ μ œμ–΄κΆŒμ„ μ™„μ „νžˆ λ„˜κΈ°κ²Œ λ˜λŠ”λ° μ œλ„ˆλ ˆμ΄ν„°μ—μ„œλŠ” 그렇지 μ•ŠμŠ΅λ‹ˆλ‹€.



νŠΉμ§•

1. μ œλ„ˆλ ˆμ΄ν„°λŠ” μ–Έμ œλ“  ν˜ΈμΆœμžμ—κ²Œ μ œμ–΄κΆŒμ„ λ„˜κΈΈ 수 μžˆμŠ΅λ‹ˆλ‹€.

2. μ œλ„ˆλ ˆμ΄ν„°λŠ” ν˜ΈμΆœν•œ μ¦‰μ‹œ μ‹€ν–‰λ˜μ§€λŠ” μ•ŠμŠ΅λ‹ˆλ‹€. λŒ€μ‹  μ΄ν„°λ ˆμ΄ν„°λ₯Ό λ°˜ν™˜ν•˜κ³ , μ΄ν„°λ ˆμ΄ν„°μ˜ next λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•¨μ— 따라 μ‹€ν–‰λ©λ‹ˆλ‹€.


이 두가지 νŠΉμ§•μ„ μ œμ™Έν•˜κ³ λŠ” 일반 ν•¨μˆ˜κ°€ λ™μΌν•˜λ‹€κ³  μ„€λͺ…ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 일단 μ œλ„ˆλ ˆμ΄ν„°λ₯Ό λ§Œλ“œλŠ” 일반적인 예제λ₯Ό ν•˜λ‚˜ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

function* gen() { 
  yield 1;
  yield 2;
  yield 3;
}

let g = gen(); // "Generator { }"

=> MDNμ—μ„œ λ‚˜μ˜€λŠ” μ˜ˆμ œμΈλ°μš” μ œλ„ˆλ ˆμ΄ν„°λŠ” function 에 * 기호λ₯Ό μ‚¬μš©ν•˜μ—¬ 선언을 ν•©λ‹ˆλ‹€. λ˜ν•œ yield ν‚€μ›Œλ“œκ°€ λ“±μž₯ν•©λ‹ˆλ‹€. μƒμ†Œν•œ 것 νˆ¬μ„±μ΄λ„€μš”. Cμ–Έμ–΄ 배울 λ•Œ ν¬μΈν„°μ—μ„œλ‚˜ μ“°λ˜ 기호인데 javascriptμ—μ„œλ„ λ“±μž₯을 ν•˜λ„€μš”.



일반적인 ν•¨μˆ˜μ™€λŠ” 달리 μ œλ„ˆλ ˆμ΄ν„°λŠ” μ΄ν„°λ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•΄ μžμ‹ μ˜ 싀행을 μ œμ–΄ν•˜λŠ” ν•¨μˆ˜λΌκ³  ν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ•„λž˜μ˜ μ½”λ“œλ₯Ό ν•œ 번 μ‚΄νŽ΄λ³΄μ£ .

function nomal() {
	for(let i=1;i<=3;i++){
		console.log(i);
	}
}

function* gen() { 
  yield 1;
  yield 2;
  yield 3;
}

let n = nomal(); // 1 2 3
let g = gen();	 // "Generator { }"
console.log(g.next()); //{ value: 1, done: false }
console.log(g.next()); //{ value: 2, done: false }
console.log(g.next()); //{ value: 3, done: false }

=> 일반적으둜 ν•¨μˆ˜λŠ” ν•œ 번 싀행이 되면 ν•¨μˆ˜κ°€ 끝날 λ•Œ κΉŒμ§€ μ‚¬μš©μžκ°€ μ œμ–΄ν•  μˆ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ„  반볡문이 λ‹€ ν•œ λ²ˆμ— 좜λ ₯λ˜μ–΄λ²„λ¦¬μ£ . 그와달리 μ œλ„ˆλ ˆμ΄ν„°λ‘œ λ§Œλ“  ν•¨μˆ˜λŠ” ν•¨μˆ˜μ˜ 싀행을 κ°œλ³„μ  λ‹¨κ³„λ‘œ λ‚˜λˆ”μœΌλ‘œμ¨ ν•¨μˆ˜μ˜ 싀행을 μ œμ–΄ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ λ‚΄κ°€ μ‹€ν–‰ν•˜λ € ν•  λ•Œ, 마치 μ±…κΉ”ν”Όλ₯Ό 껴놓은 것 처럼 이전에 μ‹€ν–‰ν–ˆλ˜ λΆ€λΆ„ λ‹€μŒλΆ€ν„° 싀행을 ν•΄μ£Όκ³  있죠. 일단 이게 κ°€μž₯ 큰 μ°¨μ΄μž…λ‹ˆλ‹€.



β“κ·ΈλŸΌ λ„λŒ€μ²΄ 이걸둜 뭘 ν•΄μ•Όν•˜λŠ”κ±΄λ°...

μ œκ°€ 보자마자 κ°–κ²Œλœ μ˜λ¬Έμž…λ‹ˆλ‹€. 사싀 κ°œλ…μ μΈ λΆ€λΆ„ μ„€λͺ…이 λ„ˆλ¬΄ λͺ¨μžλžμ§€λ§Œ, μ €λŸ° κ°„λ‹¨ν•œ μ˜ˆμ‹œλ‘œ μ •ν™•ν•œ 이해가 λ˜μ§€λ„ μ•Šκ³ , μ–΄λ–€μƒν™©μ—μ„œ μ¨μ•Όν•˜λŠ”μ§€ 감도 였질 μ•Šμ•„μ„œ λ‹€μ§œκ³ μ§œ μ–΄λ–€ μƒν™©μ—μ„œ μ“°κ²Œ λ˜λŠ”μ§€λ₯Ό μ•Œμ•„λ³΄κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.



❗️비동기적 ν”„λ‘œκ·Έλž˜λ°

κ°‘μžκΈ° λ¬Έλ²•μ΄ μ•„λ‹Œ ꡬ쑰? 에 κ΄€ν•œ μ–˜κΈ°κ°€ λ‚˜μ˜€κ²Œ λ˜μ—ˆλŠ”λ°μš”. λΉ„λ™κΈ°μ²˜λ¦¬λž€ νŠΉμ • μ½”λ“œμ˜ 싀행이 끝날 λ•Œ κΉŒμ§€ μ½”λ“œμ˜ 싀행을 λ©ˆμΆ”λŠ” 것이 μ•„λ‹ˆλΌ λ°”λ‘œ λ‹€μŒ ꡬ문을 μ‹€ν–‰ν•˜λŠ” 방식을 λ§ν•©λ‹ˆλ‹€. λΉ„λ™κΈ°μ²˜λ¦¬λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” κ²½μš°λŠ” 크게 μ„Έ 가지가 μžˆμŠ΅λ‹ˆλ‹€.


- Ajax ν˜ΈμΆœμ„ λΉ„λ‘―ν•œ λ„€νŠΈμ›Œν¬ μš”μ²­

- νŒŒμΌμ„ 읽고 μ“°λŠ” λ“±μ˜ νŒŒμΌμ‹œμŠ€ν…œ μž‘μ—…

- μ˜λ„μ μœΌλ‘œ μ‹œκ°„ 지연을 μ‚¬μš©ν•˜λŠ” κΈ°λŠ₯


μ € λ˜ν•œ λΉ„λ™κΈ°μ²˜λ¦¬λ₯Ό μœ„ν•΄ μ‚¬μš©ν–ˆλ˜ νŒ¨ν„΄μ΄ μžˆλŠ”λ°μš”, 비동기적 ν”„λ‘œκ·Έλž˜λ°μ—μ„œ λ“±μž₯ν•˜λŠ” μ„Έ 가지 νŒ¨λŸ¬λ‹€μž„μ΄ μžˆμŠ΅λ‹ˆλ‹€. 콜백과 ν”„λΌλ―ΈμŠ€ 그리고 λ§ˆμ§€λ§‰μ΄ μ΄λ²ˆμ— 닀루고 μžˆλŠ” μ œλ„ˆλ ˆμ΄ν„°μž…λ‹ˆλ‹€. 



☎️ 콜백 (callback)

μ½œλ°±μ€ κ°„λ‹¨νžˆ 말해 λ‚˜μ€‘μ— ν˜ΈμΆœν•  ν•¨μˆ˜μž…λ‹ˆλ‹€. 콜백 ν•¨μˆ˜λ„ κ·Έλƒ₯ ν•¨μˆ˜μΌ λΏμž…λ‹ˆλ‹€. 콜백이 주인곡이 μ•„λ‹ˆλ‹ˆ μ½”λ“œλ‘œ κ°„λ‹¨ν•˜κ²Œ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€. setTimeout을 μ‚¬μš©ν•˜λŠ” 예제둜 μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.


function hello(callback) {
	setTimeout(()=>{
		callback('hello')
	},500)
}
function space(text,callback) {
	setTimeout(()=>{
		callback(text + ' ');
	},500)
}
function world(text,callback) {
	setTimeout(()=>{
		callback(text + 'world');
	},500)
}
function tryWorld(){
	hello(t1=>{
		space(t1,t2=>{
			world(t2,t3=>{
				console.log(t3) //hello world
			})
		})
	})
}
tryWorld();

setTimeout 은 μ½œλ°±ν•¨μˆ˜μ˜ 싀행을 μ§€μ •λœ μ‹œκ°„λ§ŒνΌ μ§€μ—°μ‹œν‚¨ ν›„ μ‹€ν–‰ν•˜λŠ” λ‚΄μž₯ ν•¨μˆ˜μž…λ‹ˆλ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λŒ€ν‘œμ μΈ 비동기 μ²˜λ¦¬ν•¨μˆ˜μ£ . μœ„ μ˜ˆμ œλŠ” hello worldλ₯Ό 좜λ ₯ν•˜λŠ” μ˜ˆμ œμž…λ‹ˆλ‹€. 비동기 μ²˜λ¦¬ν•¨μˆ˜μ—μ„œ μˆœμ„œλ₯Ό 보μž₯ν•˜λŠ” κ²°κ³Όλ₯Ό 좜λ ₯ν•˜κΈ°μœ„ν•΄ ν•¨μˆ˜κ°€ 끝날 λ•Œλ§ˆλ‹€ κ²°κ³Όλ₯Ό μ½œλ°±ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ‘œ λ„˜κ²¨μ£Όκ³  μžˆμŠ΅λ‹ˆλ‹€.


μ½œλ°±λ§Œμ„ μ‚¬μš©ν•˜λ‹€λ³΄λ©΄ μ½œλ°±ν—¬μ— 빠질 μœ„ν—˜λ„ 있고, κ·Έλ‘œμΈν•΄ μ½”λ“œκ°€λ…μ„±λ„ 떨어지며 μ—λŸ¬μ²˜λ¦¬μ— κ³€λž€ν•œ 뢀뢄이 생길 수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έμ—λŒ€ν•œ λŒ€μ•ˆμœΌλ‘œ ν”„λΌλ―ΈμŠ€ νŒ¨ν„΄μ΄ λ“±μž₯ν•˜κ²Œ λ˜μ—ˆλŠ”λ°μš”.



πŸ€™ ν”„λΌλ―ΈμŠ€(Promise)

ν”„λΌλ―ΈμŠ€μ™€ 콜백이 λ‹€λ₯Έκ²Œ μ•„λ‹™λ‹ˆλ‹€. ν”„λΌλ―ΈμŠ€μ—μ„œλ„ μ½œλ°±μ„ μ‚¬μš©ν•©λ‹ˆλ‹€. ν”„λΌλ―ΈμŠ€μ˜ κΈ°λ³Έ κ°œλ…μ€ ν”„λΌλ―ΈμŠ€ 기반 비동기적 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ κ·Έ ν•¨μˆ˜λŠ” Promise μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. ν”„λΌλ―ΈμŠ€λŠ” 성곡 ν˜Ήμ€ μ‹€νŒ¨ 단 λ‘κ°€μ§€λ§Œ μΌμ–΄λ‚©λ‹ˆλ‹€. 


let models = require('../models');
function loginFunction(id,pwd,res,req){
	models.User.findOne({
		where: {user_id: id}
	})
	.then((user)=>{
		if(user===null || user.dataValues.password!==pwd){
			console.log('둜그인 μ‹€νŒ¨');
		} 
		else{
			console.log('둜그인 성곡');
		}
	})
	.catch((err)=>{
		console.log('였λ₯˜λ°œμƒ!!')
	})
}


μ œκ°€ Node.js μ—μ„œ μž‘μ„±ν–ˆλ˜ μ½”λ“œμ˜ μΌλΆ€λΆ„μΈλ°μš” ꡬ쑰만 보렀고 쑰금 λ‹¨μˆœν™”ν•˜μ˜€μŠ΅λ‹ˆλ‹€. 둜그인 λ™μž‘μ„ μ½”λ“œλ‘œ κ΅¬ν˜„ν•œ 것인데, λ³΄μ‹œλ©΄ findOne λ©”μ†Œλ“œ 이후에 then μ΄ λ‚˜μ˜€μ£ . 이 말은 findOne λ©”μ†Œλ“œμ˜ κ²°κ³Όκ°€ μ„±κ³΅ν–ˆλ‹€λŠ” λΆ€λΆ„μž…λ‹ˆλ‹€. μœ„μ—μ„œ λ§ν–ˆλ“―μ΄ PromiseλŠ” 성곡 ν˜Ήμ€ μ‹€νŒ¨ 단 λ‘κ°€μ§€μ˜ 경우만 λ°œμƒν•œλ‹€κ³  ν•˜μ˜€μ£ . 


그럼 catch λŠ”? μ‹€νŒ¨ν•œ 경우λ₯Ό λ°˜ν™˜ν•˜κ² μ£ . μœ„ κ²½μš°μ—λŠ” λ‘œκ·ΈμΈμ„ μ‹€νŒ¨ν–ˆλ‹€λŠ” 말이 μ•„λ‹ˆλΌ DB μ ‘κ·Ό μžμ²΄κ°€ 잘λͺ»λœ 경우λ₯Ό λœ»ν•©λ‹ˆλ‹€. 예λ₯Όλ“€λ©΄ User ν…Œμ΄λΈ”μ΄ μ•„λ‹Œ μ΄μƒν•œ ν…Œμ΄λΈ”μ„ μ ‘κ·Όν•˜λ €ν–ˆλ‹€λ˜κ°€ ν•˜λŠ” κ²½μš°κ°€ 있겠죠? ν”„λΌλ―ΈμŠ€ νŒ¨ν„΄ μ΄λΌκ³ λŠ” ν–ˆμ§€λ§Œ λ³΄μ‹œλ‹€μ‹œν”Ό 콜백이 μ—†λŠ”κ²Œ μ•„λ‹ˆμ£ . μ•„λ¬΄λž˜λ„ 가독성이 μ’‹κ³  μ—λŸ¬μ²˜λ¦¬λ„ catch문으둜 λͺ…ν™•ν•˜κ²Œ μ²˜λ¦¬ν•  수 μžˆλ‹€λ³΄λ‹ˆ 많이 μ“°λŠ” νŒ¨ν„΄ 쀑 ν•˜λ‚˜ μž…λ‹ˆλ‹€. 


μœ„ 두 νŒ¨λŸ¬λ‹€μž„μ€ μœ„μ˜ κ°œλ…μ΄ 끝이라고 ν•  수 μ—†μŠ΅λ‹ˆλ‹€. μ›Œλ‚™ 많이 쓰이고 더 μœ μš©ν•œ κΈ°λŠ₯μ΄λ‚˜ κ°œμ„ λœ ν˜•νƒœκ°€ 많이 μžˆκ±°λ“ μš”. 비동기 μ²˜λ¦¬μ— λŒ€ν•œ λ‚΄μš©μ„ μ•Œμ•„λ΄μ•Όν•˜λ‹ˆ κ°„λ‹¨ν•˜κ²Œλ‚˜λ§ˆ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€.



πŸ’‘μ œλ„ˆλ ˆμ΄ν„°

콜백 예제λ₯Ό μ΄μš©ν•΄μ„œ μ œλ„ˆλ ˆμ΄ν„°λ‘œ ν‘œν˜„ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€. 


function helloWorld_Hello() {
  setTimeout(() => {
    iterator.next('Hello');
  }, 1000);
}
 
function helloWorld_Space(text) {
  setTimeout(() => {
    iterator.next(text + ' ');
  }, 1000);
}
 
function helloWorld_World(text) {
  setTimeout(() => {
    iterator.next(text + 'World');
  }, 1000);
}
 
function* helloWorld() {
    const hello = yield helloWorld_Hello();
    const space = yield helloWorld_Space(hello);
    const world = yield helloWorld_World(space);
    console.log(world); // Hello World
    return;
}
const iterator = helloWorld();
iterator.next();

μœ„μ˜ 콜백 μ˜ˆμ œμ™€ λ‹€λ₯Έμ μ΄ μžˆλ‹€λ©΄ helloWorld ν•¨μˆ˜λ₯Ό μ œλ„ˆλ ˆμ΄ν„°λ‘œ μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ 각각의 ν•¨μˆ˜λ“€μ€ μ°¨λ‘€μ°¨λ‘€ 싀행이 λ©λ‹ˆλ‹€. Helloκ°€ μ‹€ν–‰λœ ν›„ Space, λ§ˆμ§€λ§‰μœΌλ‘œ Worldκ°€ 싀행이 되게되죠. 


μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ λ°”λ‘œ 싀행이 λ˜λŠ” 것이 μ•„λ‹ˆλΌ μ΄ν„°λ ˆμ΄ν„° 객체λ₯Ό λ°˜ν™˜ν•˜κ²Œ λ©λ‹ˆλ‹€. κ·Έλž˜μ„œ 싀행을 μ‹œν‚€λ €λ©΄ next λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•΄μ•Όν•©λ‹ˆλ‹€.


μ΄λ²ˆμ— μ œλ„ˆλ ˆμ΄ν„°λ₯Ό 처음 μ•Œκ²Œ λ˜μ—ˆλŠ”λ° μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 비동기 처리λ₯Ό μœ„ν•΄ μ œκ³΅ν•˜λŠ” λͺ¨λ“ˆμ΄ μ—¬λŸ¬κ°€μ§€ μžˆλ‹€λ³΄λ‹ˆ 였히렀 이게 더 λΆˆνŽΈν•˜λ‹€λŠ” λŠλ‚Œλ„ λ“œλŠ”κ²Œ μ‚¬μ‹€μž…λ‹ˆλ‹€. μ œλ„ˆλ ˆμ΄ν„°μ˜ 강점이 λ“œλŸ¬λ‚˜λŠ” μ½”λ“œλ₯Ό λ§Œλ‚˜κ²Œλ˜λ©΄ λ‹€μ‹œν•œλ²ˆ μ‚΄νŽ΄λ΄μ•Όκ² λ„€μš”.. 



예제 좜처  : https://lab.falsy.me/generator-co-async-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%88%9C%EC%B0%A8-%EC%8B%A4%ED%96%89%EC%8B%9C%ED%82%A4%EA%B8%B0/

'javascript > λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[javascript] - Promise bulk둜 μ²˜λ¦¬ν•˜κΈ°  (0) 2023.02.10
8. iterators + for..of  (0) 2019.01.11
7. let + const  (0) 2019.01.06
6. default + rest + spread  (0) 2019.01.03
5. destructuring  (0) 2018.12.31
λŒ“κΈ€
곡지사항
μ΅œκ·Όμ— 올라온 κΈ€
μ΅œκ·Όμ— 달린 λŒ“κΈ€
Total
Today
Yesterday
링크
Β«   2024/12   Β»
일 μ›” ν™” 수 λͺ© 금 ν† 
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
κΈ€ 보관함