TIL 9일차 (20230104)

박세연·2024년 1월 4일

TIL

목록 보기
8/70

4주차는 콜백함수

  • 어제차에 콜백함수의 경우 this를 미리 지정하면 지정 객체를 지칭한다고 했는데 오늘 그 예시로 addEventListener을 배웠다.
    document.body.querySelector('#a').addEventListener(~~)에서 밑줄 친 부분이 그 대상인 것!

  • forEach, map, filter에서 콜백함수를 넣을 때 ()을 넣지 말아야한다(넣으면 출력값이 나오는 것이므로 함수명만 넣기)

콜백 함수 내부의 this에 다른 값 바인딩하기

  • bind 메서드의 활용
var obj1 = {
	name: 'obj1',
	func: function () {
		console.log(this.name);
	}
};
//함수 자체를 obj1에 바인딩
//obj1.func를 실행할 때 무조건 this는 obj1로 고정해줘!
setTimeout(obj1.func.bind(obj1), 1000);

var obj2 = { name: 'obj2' };
//함수 자체를 obj2에 바인딩
//obj1.func를 실행할 때 무조건 this는 obj2로 고정해줘!
setTimeout(obj1.func.bind(obj2), 1500);

콜백 지옥과 비동기 제어

  • 콜백 지옥: 익명의 함수로 전달하는 과정이 반복되어 가독성이 매우 떨어짐
  • 동기: 차례차례 실행되는 것 (처음 것이 끝나야 다음 것으로 진행)
  • 비동기: 실행중인 코드의 완료 여부와 무관하게 즉시 다음 코드 실행), 별도의 요청, 실행 대기, 보류 등과 관련된 코드

🚩 콜백 지옥 해결 방법

  1. 기명 함수로 변환

  2. 비동기 작업의 동기적 표현
    2-1. Promise
    : new 연산자로 호출한 promise의 인자로 넘어가는 콜백은 바로 실행됨, resolve(실행)나 reject(거절) 호출 구문이 있으면 둘중 하나가 실행되기 전까진 then이나 catch(오류)로 넘어가지 않음

    ```
    new Promise(function (resolve) {
    setTimeout(function () {
    	var name = '에스프레소';
    	console.log(name);
    	resolve(name);
    }, 500);
    }).then(function (prevName) {
    return new Promise(function (resolve) {
    	setTimeout(function () {
    		var name = prevName + ', 아메리카노';
    		console.log(name);
    		resolve(name);
    	}, 500);
    });
    }).then(function (prevName) {
    return new Promise(function (resolve) {
    	setTimeout(function () {
    		var name = prevName + ', 카페모카';
    		console.log(name);
    		resolve(name);
    	}, 500);
    });
    }).then(function (prevName) {
    return new Promise(function (resolve) {
    	setTimeout(function () {
    		var name = prevName + ', 카페라떼';
    		console.log(name);
    		resolve(name);
    	}, 500);
    });
    });
    ```

    2-2. Promise 중 then반복

    var addCoffee = function (name) {
    	return function (prevName) {
    		return new Promise(function (resolve) {
    			setTimeout(function () {
    				var newName = prevName ? (prevName + ', ' + name) : name;
    				console.log(newName);
    				resolve(newName);
    			}, 500);
    		});
    	};
    };
    
    addCoffee('에스프레소')()
    	.then(addCoffee('아메리카노'))
    	.then(addCoffee('카페모카'))
    	.then(addCoffee('카페라떼'));

    2-3. Generator
    : *붙은 함수가 generator 함수로, iterator 객체(next()가짐)가 반환됨. iterator은 next 메서드 호출 시 yield에서 잠시 멈춘 후 실행을 반복하여 동기처럼 진행됨

    var addCoffee = function (prevName, name) {
    	setTimeout(function () {
    		coffeeMaker.next(prevName ? prevName + ', ' + name : name);
    	}, 500);
    };
    var coffeeGenerator = function* () {
    	var espresso = yield addCoffee('', '에스프레소');
    	console.log(espresso);
    	var americano = yield addCoffee(espresso, '아메리카노');
    	console.log(americano);
    	var mocha = yield addCoffee(americano, '카페모카');
    	console.log(mocha);
    	var latte = yield addCoffee(mocha, '카페라떼');
    	console.log(latte);
    };
    var coffeeMaker = coffeeGenerator();
    coffeeMaker.next();

    2-4. Promise + Async/await
    : 비동기 작업을 수행코자 하는 함수 앞에 aync, 함수 내부에서 실질적인 비동기 작업이 필요한 위치마다 await 붙이기

    var addCoffee = function (name) {
    	return new Promise(function (resolve) {
    		setTimeout(function(){
    			resolve(name);
    		}, 500);
    	});
    };
    var coffeeMaker = async function () {
    	var coffeeList = '';
    	var _addCoffee = async function (name) {
    		coffeeList += (coffeeList ? ', ' : '') + await addCoffee(name);
    	};
    	await _addCoffee('에스프레소');
    	console.log(coffeeList);
    	await _addCoffee('아메리카노');
    	console.log(coffeeList);
    	await _addCoffee('카페모카');
    	console.log(coffeeList);
    	await _addCoffee('카페라떼');
    	console.log(coffeeList);
    };
    coffeeMaker();
profile
배워나가는 중

0개의 댓글