12/08/2018, 11:40

Giới thiệu Cache trong angularjs

1. Cache là gì? Cache là một thành phần lưu trữ Data để sử dụng cho các request tiếp theo trong tương lai có thể lấy response một cách nhanh hơn trả về cho client. Nó thích hợp với các dữ liệu không cần tính toán lại thường xuyên, khi người dùng fetch lại dữ liệu thì kết quả không thay đổi. Khi ...

1. Cache là gì?

Cache là một thành phần lưu trữ Data để sử dụng cho các request tiếp theo trong tương lai có thể lấy response một cách nhanh hơn trả về cho client. Nó thích hợp với các dữ liệu không cần tính toán lại thường xuyên, khi người dùng fetch lại dữ liệu thì kết quả không thay đổi.

Khi đó chúng ta sẽ lấy kết quả ngay từ trong bộ nhớ Cache, Điều này sẽ tối ưu hóa hiệu xuất của hệ thống.

Tùy thuộc vào mức độ thay đổi thường xuyên của dữ liệu mà ta sẽ quy định thời gian lưu trữ của Cache.

Cache sẽ làm việc theo kiểu Key/value. Key sẽ dùng để tham chiếu tới nội dung của Cache. khi một request được gọi, nếu key tồn tại trong cache và cache còn khả dụng (tức mà cache Hit) thì value của cache ứng với key đó được get ra trả về cho client. Ngược lại thì là Cache Miss. Khi đó ta sẽ tiến hành fetch dữ liệu bình thường để trả ra cho client, đồng thời lưu vào cache phục vụ cho lần request tiếp theo.

Trong bài viết này tôi sẽ đề cập đến Cache trong Angularjs.

2. Cache trong Angular

Angular cache là một tính năng mới vượt ra ngoài những dịch vu tích hợp (build-in services), nó cung cấp cho chúng ta khả năng sử dụng các cơ chế để lưu trữ và tùy chỉnh content trong cache.

3. $$acheFactory

Angularjs sử dụng $cacheFactory để quản lý, khởi tạo cũng như thao tác với Cache.

$$acheFactory là một dịch vụ để tạo ra một đối tượng cache.

var cache = $cacheFactory('demoCache');

Trên đây là đoạn code dùng để tạo ra một đối tượng cache. Bằng cách khai báo trên ta đã tạo ra một cache Object với ID là "demoCache"

Bạn cũng có thể thêm một số options khi khai báo đối tượng Cache của mình bằng cách thêm options đó vào tham số thứ hai:

   var myCache =  $cacheFactory('demoCache', {
        capacity: 3 // optional - turns the cache into LRU cache
    });

capacity là một options để quy định số lượng cặp key-value tối đa là 3. nếu xuất hiện cặp giá trị thứ 4 thì cặp giá trị được lưu với thời gian lâu nhất sẽ bị xóa đi.

$$acheFactory sẽ tạo ra một đối tượng Cache. Angularjs cung cấp cho chúng ta một số phương thức để thao tác với Cache Object như: get(), put(), removavascripte(), removeAll(), info(), destroy().

Ví dụ minh họa

  • Khai báo DemoCache factory thuộc modul 'demoCacheApp'
angular.module('demoCacheApp', []).
factory('DemoCache', function($cacheFactory) {
    return $cacheFactory('demoCache', {
        capacity: 3 // optional - turns the cache into LRU cache
    });
})

phần khai báo này giống như giới thiệu ở trên thôi. ko có gì đặc biệt.

Tôi sẽ tạo một Controller và các function dùng để thực hiện phép tính số học và in ra kết quả rồi tiến hành lưu phép tính và kết quả đó vào cache. Với những lần tính toán tiếp theo, Ta chỉ cần lấy số liệu đã tính trong cache hiển thị ra luôn.

  • Khai báo Controller
var MyCacheController = function($scope, DemoCache) {}

viết hàm tính toán:

   $scope.tinhtoan = function() {
        var equation = $scope.equation,
            result = DemoCache.get(equation),
            status = 'Kết quả lấy ra từ Cache';
        if (!result) {
            status = 'Kết quả đc tính toán';
            result = eval(equation);
            DemoCache.put(equation, result);
        }
        $scope.result = result;
        $scope.status = status;
        $scope.cacheInfo = DemoCache.info();
    }

equation là phép toán bạn nhập vào.

result là hết quả của phép toán.

status là cờ giúp bạn nhận biết là kết quả đc lấy ra từ Cache hay không.

$cacheFactory cung cấp phương thức get() để lấy ra value ứng với keys được lưu trữ trong cache. bằng cách:

result = DemoCache.get(equation)

Nếu phép tính chưa được tính trước đó thì ta sẽ tính toán kết quả và đẩy nó vào trong cache

     if (!result) {
            status = 'Kết quả đc tính toán';
            result = eval(equation);
            DemoCache.put(equation, result);
        }

Để lưu cache bạn dùng phương thức put() kèm theo hai tham số lần lượt là keys và value của cache.

  • Lấy Cache info:
$scope.cacheInfo = DemoCache.info();
``
+ Xóa Cache
```javascript

$scope.clearCache = function() {
        DemoCache.removeAll();
}

Bạn cũng có thể xóa Cache theo key mà mình mong muốn bằng phương thức remove():

 DemoCache.remove(key);

  • View
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<script src="/app.js"></script>
<div ng-app="demoCacheApp">
  <div ng-controller="MyCacheController">
      <input ng-model="equation" on-enter="tinhtoan()"/>
      <button ng-click="tinhtoan()">Thuc hien</button><br/>
      <input ng-model="result"/> {{status}}<br/>
      {{cacheInfo}}<br/>
      <button ng-click="clearCache()">Xoa cache</button>
  </div>
</div>

1.png

Lần đầu kết quả sẽ được tính toán.

Tiếp tục thực hiện phép toán trên kết quả sẽ được lấy ra từ cache

2.png

##4. Cache thông qua $$ttp

Service $http có thể tạo một cache với ID là $http với thao tác khá đơn giản là set "cache: true" khi thực hiện requets thông qua $http.

$http.get('/users.json', {
  cache: true
});

Bằng cách đó mọi requets tới '/users.json' đều được lưu lại trong cache thông qua cache object có tên là "$http"

Để lấy ra cache của http ta vẫn dùng phương thức `get` của `cacheFactory`:

var cache = $cacheFactory.get('$http');

Giá trị trong $http cache được lưu theo dạng:

Key là url trong request của $$ttp.

Value là content của response trả về.

###Ví dụ

  • Tôi tạo 1 controller để load danh sách users
myApp.controller("UserListCtr", ['$scope', '$http', '$resource', 'Users', 'User', '$location', function($scope, $http, $resource, Users, User, $location) {

  $scope.loadUsers = function() {
    // alert("Aready got data from sever");
    $http.get("http://localhost:9000/users.json").success(function(data) {
      $scope.users = data;
    }).error(function(){});
  };
  $scope.loadUsers();
}]);

Bởi mặc định thì cache cho $$ttp được set là false

$http.get("http://localhost:9000/users.json")

  • Tạo 1 'button' trên view để gọi function 'loadUsers'
<button ng-click="loadUsers()">load users</button>

Mỗi lần nhấn "load users" $$ttp sẽ thực hiện 1 request đên controler:

3.png

4.png

  • Bây giờ, set cache thành true:
$http.get("http://localhost:9000/users.json", {cache:true})

khi nhấn "load users" sẽ không reuqest lên server nữa.

Như đã nói ở trên key của $$ttp cache là url của requet vì vậy ta có thể get thông tin của nó thông qua key này:

$scope.removeHttpCache = function(){
    var userCache = $cacheFactory.get('$http');
    console.log("userCache: ", userCache.get("http://localhost:9000/users.json"));
    userCache.remove("http://localhost:9000/users.json")
  };

  • tạo nút remove cache và bấm vào:
<button ng-click="removeHttpCache()">remove cache</button>

kết quả là khi bấm vào lần thứ nhất console hiển thị userCache và sau đó xóa cache đi.

Tiếp tục bấm vào thì userCache sẽ undefine bởi vì nó đã bị xóa đi. 5.png

###Custome $$ttp cache

Mặc định http cache sẽ có ID là &quothttp" nhưng bạn cũng có thể thay đổi nó. bằng cách sau:

myApp.factory("usersCache", function($cacheFactory){
  return $cacheFactory('usersCached');
});

và thay đổi thuộc tính cache: true thành cache:usersCache như vậy thay vì sử dụng default cache thì $$ttp sẽ sử dụng cache được custome của bạn "usersCache"

##Thank for reading

Github resources:

1. Demo cache with $$acheFactory

2. Demo $$ttp cache

0