gc.spec.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import {
  2. type ComputedRef,
  3. computed,
  4. effect,
  5. effectScope,
  6. reactive,
  7. shallowRef as ref,
  8. toRaw,
  9. } from '../src/index'
  10. import { getDepFromReactive } from '../src/dep'
  11. describe.skipIf(!global.gc)('reactivity/gc', () => {
  12. const gc = () => {
  13. return new Promise<void>(resolve => {
  14. setTimeout(() => {
  15. global.gc!()
  16. resolve()
  17. })
  18. })
  19. }
  20. // #9233
  21. it.todo('should release computed cache', async () => {
  22. const src = ref<{} | undefined>({})
  23. // @ts-expect-error ES2021 API
  24. const srcRef = new WeakRef(src.value!)
  25. let c: ComputedRef | undefined = computed(() => src.value)
  26. c.value // cache src value
  27. src.value = undefined // release value
  28. c = undefined // release computed
  29. await gc()
  30. expect(srcRef.deref()).toBeUndefined()
  31. })
  32. it.todo('should release reactive property dep', async () => {
  33. const src = reactive({ foo: 1 })
  34. let c: ComputedRef | undefined = computed(() => src.foo)
  35. c.value
  36. expect(getDepFromReactive(toRaw(src), 'foo')).not.toBeUndefined()
  37. c = undefined
  38. await gc()
  39. await gc()
  40. expect(getDepFromReactive(toRaw(src), 'foo')).toBeUndefined()
  41. })
  42. it('should not release effect for ref', async () => {
  43. const spy = vi.fn()
  44. const src = ref(0)
  45. effect(() => {
  46. spy()
  47. src.value
  48. })
  49. expect(spy).toHaveBeenCalledTimes(1)
  50. await gc()
  51. src.value++
  52. expect(spy).toHaveBeenCalledTimes(2)
  53. })
  54. it('should not release effect for reactive', async () => {
  55. const spy = vi.fn()
  56. const src = reactive({ foo: 1 })
  57. effect(() => {
  58. spy()
  59. src.foo
  60. })
  61. expect(spy).toHaveBeenCalledTimes(1)
  62. await gc()
  63. src.foo++
  64. expect(spy).toHaveBeenCalledTimes(2)
  65. })
  66. it('should release computed that untrack by effect', async () => {
  67. const src = ref(0)
  68. // @ts-expect-error ES2021 API
  69. const c = new WeakRef(computed(() => src.value))
  70. const scope = effectScope()
  71. scope.run(() => {
  72. effect(() => c.deref().value)
  73. })
  74. expect(c.deref()).toBeDefined()
  75. scope.stop()
  76. await gc()
  77. expect(c.deref()).toBeUndefined()
  78. })
  79. it('should release computed that untrack by effectScope', async () => {
  80. const src = ref(0)
  81. // @ts-expect-error ES2021 API
  82. const c = new WeakRef(computed(() => src.value))
  83. const scope = effectScope()
  84. scope.run(() => {
  85. c.deref().value
  86. })
  87. expect(c.deref()).toBeDefined()
  88. scope.stop()
  89. await gc()
  90. expect(c.deref()).toBeUndefined()
  91. })
  92. })