var obj = {
vals: [1, 2, 3],
logValues: function (v, i) {
console.log(this, v, i);
},
};
obj.logValues(1, 2); // {vals: [1, 2, 3], logValues: f} 1 2
[4, 5, 6].forEach(obj.logValues); // Window {...} 4 0
// Window {...} 5 1
// Window {...} 6 2객체의 메서드를 콜백 함수로 전달하면 해당 객체를 this로 바라볼 수 없게 됨
ES5 이전에는 this를 다른 변수에 담아 콜백 함수로 활용할 함수에 this대신 그 변수를 사용하게 하고 클로저로 만들었음.
var obj1 = {
name: "obj1",
func: function () {
var self = this;
return function () {
console.log(self.name);
};
},
};
var callback = obj1.func();
setTimeout(callback, 1000);ES5 이후에는 bind 메서드를 이용함
var obj1 = {
name: "obj1",
func: function () {
console.log(this.name);
},
};
setTimeout(obj1.func.bind(obj1), 1000);
var obj2 = { name: "obj2" };
setTimeout(obj1.func.bind(obj2), 1500);
콜백 지옥 콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상
동기: 현재 실행 중인 코드가 완료된 후에야 다음 코드를 실행하는 방식
비동기: 현재 실행 중인 코드의 완료 여부와 무관하게 즉시 다음 코드로 넘어감
별도의 요청, 실행 대기, 보류 등과 관련된 코드는 비동기적인 코드콜백 지옥 해결
기명함수로 변환
비동기 작업의 동기적 표현
1. Promise
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("카페모카"));2. Generator
ES6 Generator는 function에 * 을 붙여서 정의하면 generator함수가 됨
yield로 실행을 멈추는 곳을 지정할 수 있음
실행을하면 iterator객체가 반환되며, .next()를 호출하면 멈췄던 곳부터 다시 시작
비동기 작업이 완료되는 시점마다 next 메서드를 호출한다면 Generator 함수 내부의 소스가 위에서 아래로 순차적으로 실행됨
var addCoffee = function (prevName, name) {
setTimeout(function () {
coffeeMaker.next(prevName ? prevName + ", " + name : name);
}, 500);
};
var coffeeGenerator = function* () {
var espresso = yield addCoffee("", "에스프레소");
var americano = yield addCoffee(espresso, "아메리카노");
var mocha = yield addCoffee(americano, "카페모카");
};
var coffeeMaker = coffeeGenerator();
coffeeMaker.next();
async/await
ES2017 async/await 가독성이 뛰어나고 작성법도 간단 -> (프로젝트하면서 개인적으로 이것만 쓴 것 같음)
비동기 작업을 수행하려는 함수 앞에 async를 표기하고 함수 내부의 비동기 작업이 필요한 위치마다 await를 표기
이렇게 해서 뒤의 내용들이 Promise로 전환되고 해당 내용이 resolve된 이후 다음 작업이 진행됨. Promise의 then과 흡사한 효과를 볼 수 있음
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("에스프레소");
await _addCoffee("아메리카노");
await _addCoffee("카페모카");
};
coffeeMaker();