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 함수로 전달하여 처리 할 수 있도록 하면 되는 것이였다.