gc.spec.ts 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import {
  2. type ComputedRef,
  3. computed,
  4. effect,
  5. reactive,
  6. shallowRef as ref,
  7. toRaw,
  8. } from '../src/index'
  9. import { getDepFromReactive } from '../src/dep'
  10. describe.skipIf(!global.gc)('reactivity/gc', () => {
  11. const gc = () => {
  12. return new Promise<void>(resolve => {
  13. setTimeout(() => {
  14. global.gc!()
  15. resolve()
  16. })
  17. })
  18. }
  19. // #9233
  20. it('should release computed cache', async () => {
  21. const src = ref<{} | undefined>({})
  22. // @ts-expect-error ES2021 API
  23. const srcRef = new WeakRef(src.value!)
  24. let c: ComputedRef | undefined = computed(() => src.value)
  25. c.value // cache src value
  26. src.value = undefined // release value
  27. c = undefined // release computed
  28. await gc()
  29. expect(srcRef.deref()).toBeUndefined()
  30. })
  31. it('should release reactive property dep', async () => {
  32. const src = reactive({ foo: 1 })
  33. let c: ComputedRef | undefined = computed(() => src.foo)
  34. c.value
  35. expect(getDepFromReactive(toRaw(src), 'foo')).not.toBeUndefined()
  36. c = undefined
  37. await gc()
  38. await gc()
  39. expect(getDepFromReactive(toRaw(src), 'foo')).toBeUndefined()
  40. })
  41. it('should not release effect for ref', async () => {
  42. const spy = vi.fn()
  43. const src = ref(0)
  44. effect(() => {
  45. spy()
  46. src.value
  47. })
  48. expect(spy).toHaveBeenCalledTimes(1)
  49. await gc()
  50. src.value++
  51. expect(spy).toHaveBeenCalledTimes(2)
  52. })
  53. it('should not release effect for reactive', async () => {
  54. const spy = vi.fn()
  55. const src = reactive({ foo: 1 })
  56. effect(() => {
  57. spy()
  58. src.foo
  59. })
  60. expect(spy).toHaveBeenCalledTimes(1)
  61. await gc()
  62. src.foo++
  63. expect(spy).toHaveBeenCalledTimes(2)
  64. })
  65. })