Logo

Cơ chế cached của computed trong VueJS

Vì sao computed lại có cache, không phải nó sẽ luôn re-run khi các reactive dependencies bên trong thay đổi sao?

Bản chất computed là lazy nó không chạy lần đầu (trừ khi sử dụng nó trên template)

Khi thực hiện xong một tính toán, nó luôn cache lại một giá trị result. Bất kỳ lúc nào mà computed nhận thấy người dùng cố truy cập giá trị của nó, mà không có một dependency nào được mark là dirty thì nó lập tức trả ra giá trị đã cache trước đó mà không chạy các bước trung gian

Chi Tiết

Khi thay đổi một biến reactive ref thì việc thay đổi giá trị của các subcriber biến ref này chưa diễn ra ngay. nó chỉ đơn giản thông báo đến các subcriber là nó đã bị dirty. và việc truy cập vào một subcriber nhất định khi có dependency là một ref được đánh dấu là dirty sẽ force subcriber đó tính toán lại (computed, watch).

Theo Ví dụ dưới đây:

const reactiveVariable1 = ref(1);

const doubleReactive1 = computed(() => 2 * reactiveVariable1.value)

function changeReactiveValueMultipleTime () {
  reactiveVariable1.value = 12
  console.log(doubleReactive1.);

  for (let index = 0; index < 20; index++) {
     reactiveVariable1.value += index;
  }
  console.log(doubleReactive1.value)
}

computed doubleReactive1 sẽ chỉ chạy lại 2 lần. mặc dù dependency của nó (reactiveVariable1) được thay đổi đến tận 21 lần. nhưng mọi chuyện sẽ khác nếu chúng ta cố tình truy cập vào computed này khi đang trong vòng lặp, sau khi thay đổi giá trị của reactiveVariable1. nó sẽ liên tục nhận ra reactiveVariable1 đã bị dirty và liên tục tính toán và cache lại.