javascript callback 관련
javascript에서 callback 함수에 관한 글 중에서 비동기 처리 방식에 관련하여 callback이 많이 사용된다는 것을 알았다.
나도 같은 경우가 발생되었다.
angluarjs로 사이트를 만들던 중 data-obejct 관련된 글을 보게 되었다.
http://www.webdeveasy.com/angularjs-data-model/
여기서 확인했을때 각 entity별로 crud 등을 수행 할 수 있도록 data-object 객체를 만들고 화면단에서는 해당 기능을 호출하는 방식으로 개발하도록 하는 방법이다.
아래 angularjs.factory를 이용하여 Book 의 Crud를 만들었다.
Book model service
app.factory('Book', ['$http', function($http) {
function Book(bookData) {
if (bookData) {
this.setData(bookData):
}
// Some other initializations related to book
};
Book.prototype = {
setData: function(bookData) {
angular.extend(this, bookData);
},
load: function(id) {
var scope = this;
$http.get('ourserver/books/' + bookId).success(function(bookData) {
scope.setData(bookData);
});
},
delete: function() {
$http.delete('ourserver/books/' + bookId);
},
update: function() {
$http.put('ourserver/books/' + bookId, this);
},
getImageUrl: function(width, height) {
return 'our/image/service/' + this.book.id + '/' + width + '/' + height;
},
isAvailable: function() {
if (!this.book.stores || this.book.stores.length === 0) {
return false;
}
return this.book.stores.some(function(store) {
return store.quantity > 0;
});
}
};
return Book;
}]);
그리고 controller에서 만들어진 service 객체를 가져와서 사용하는 부분이다.
BookController that uses Book model
app.controller('BookController', ['$scope', 'Book', function($scope, Book) {
$scope.book = new Book();
$scope.book.load(1);
}]);
좀더 확장해서 기능을 구현할 때 문제가 발생되었다.
서비스 수정**
app.factory('Book', ['$http', function($http) {
function Book(bookData) {
if (bookData) {
this.setData(bookData):
}
// Some other initializations related to book
};
Book.prototype = {
setData: function(bookData) {
angular.extend(this, bookData);
},
load: function(id) {
var scope = this;
$http.get('ourserver/books/' + bookId).success(function(bookData) {
scope.setData(bookData);
});
},
delete: function() {
$http.delete('ourserver/books/' + bookId);
},
update: function() {
$http.put('ourserver/books/' + bookId, this);
},
save : function (data) { // save 펑션 추가
$http.post('ourserver/books')
.success(function(data){
this.setData(data);
});
}
getImageUrl: function(width, height) {
return 'our/image/service/' + this.book.id + '/' + width + '/' + height;
},
isAvailable: function() {
if (!this.book.stores || this.book.stores.length === 0) {
return false;
}
return this.book.stores.some(function(store) {
return store.quantity > 0;
});
}
};
return Book;
}]);
컨트롤러 수정
app.controller('BookController', ['$scope', 'Book', function($scope, Book) {
$scope.book = new Book();
$scope.book.load(1);
// book 저장
$scope.saveData = function (data) {
$scope.book.save(data);
$scope.data = $scope.book;
}
}]);
Book 정보를 입력 후 서버에서 생성된 bookId 와 입력 한 정보를 Book 객체 안에서 setData 시킨 뒤
그 정보를 화면단 data에다가 넣어 줄려고 할때 발생되었다.
book 정보를 불러올 수 없게 된 것이다.
이유는 $scope.book.save() function을 호출하고 처리 후 데이터를 화면단 scope에 넣는 방식으로 되어야 하는데 이때 비동기적으로 data가 save 후 setData를 시킨다는 것을 간과한 것이다.
너무 절차적으로 코드를 작성하는 것에 익숙했다가 잠시 비동기적 처리가 추가되다보니 이런 문제가 발생된 것이다.
이때 좀더 생각을 할 수 있었으면 좋으련만
친구가 도움을 준 방법으로 callback 방식으로 처리 할 수 있었다.
서비스 수정**
app.factory('Book', ['$http', function($http) {
function Book(bookData) {
if (bookData) {
this.setData(bookData):
}
// Some other initializations related to book
};
Book.prototype = {
setData: function(bookData) {
angular.extend(this, bookData);
},
load: function(id) {
var scope = this;
$http.get('ourserver/books/' + bookId).success(function(bookData) {
scope.setData(bookData);
});
},
delete: function() {
$http.delete('ourserver/books/' + bookId);
},
update: function() {
$http.put('ourserver/books/' + bookId, this);
},
save : function (data, callback) { // save 펑션 추가, callback 함수 추가
$http.post('ourserver/books')
.success(function(data){
this.setData(data);
// 처리 후 callback 호출
callback();
});
}
getImageUrl: function(width, height) {
return 'our/image/service/' + this.book.id + '/' + width + '/' + height;
},
isAvailable: function() {
if (!this.book.stores || this.book.stores.length === 0) {
return false;
}
return this.book.stores.some(function(store) {
return store.quantity > 0;
});
}
};
return Book;
}]);
컨트롤러 수정**
app.controller('BookController', ['$scope', 'Book', function($scope, Book) {
$scope.book = new Book();
$scope.book.load(1);
// book 저장
$scope.saveData = function (data) {
$scope.book.save(data,function(){
$scope.data = $scope.book;
});
}
}]);
간단하게 예제로 설명하였다. 저런 방식으로 비동기 처리 후 다음 절차를 callback 함수로 전달하여 처리 할 수 있도록 하면 되는 것이였다.