瀏覽代碼

forgot memoized-rendering file, add equality funcs

Adam Shaw 7 年之前
父節點
當前提交
6c01fa80d8
共有 2 個文件被更改,包括 63 次插入3 次删除
  1. 52 0
      src/component/memoized-rendering.ts
  2. 11 3
      src/util/array.ts

+ 52 - 0
src/component/memoized-rendering.ts

@@ -0,0 +1,52 @@
+import { isArraysEqual, EqualityFuncs } from '../util/array'
+
+export interface MemoizedRendering<ArgsType extends any[]> {
+  (...args: ArgsType): void
+  unrender: () => void
+  dependents: MemoizedRendering<any>[]
+}
+
+export function memoizeRendering<ArgsType extends any[]>(
+  renderFunc: (...args: ArgsType) => void,
+  unrenderFunc?: (...args: ArgsType) => void,
+  dependencies: MemoizedRendering<any>[] = [],
+  equalityFuncs: EqualityFuncs = []
+): MemoizedRendering<ArgsType> {
+
+  let dependents: MemoizedRendering<any>[] = []
+  let thisContext
+  let prevArgs
+
+  function unrender() {
+    if (prevArgs) {
+
+      for (let dependent of dependents) {
+        dependent.unrender()
+      }
+
+      if (unrenderFunc) {
+        unrenderFunc.apply(thisContext, prevArgs)
+      }
+
+      prevArgs = null
+    }
+  }
+
+  function res() {
+    if (!prevArgs || !isArraysEqual(prevArgs, arguments, equalityFuncs)) {
+      unrender()
+      thisContext = this
+      prevArgs = arguments
+      renderFunc.apply(this, arguments)
+    }
+  }
+
+  res.dependents = dependents
+  res.unrender = unrender
+
+  for (let dependency of dependencies) {
+    dependency.dependents.push(res)
+  }
+
+  return res
+}

+ 11 - 3
src/util/array.ts

@@ -33,16 +33,24 @@ export function removeExact(array, exactVal) {
 }
 
 
-export function isArraysEqual(a0, a1) {
+export type EqualityFuncs = (null | ((obj0, obj1) => boolean))[]
+
+export function isArraysEqual(a0, a1, equalities: EqualityFuncs = []) {
   let len = a0.length
   let i
 
-  if (len == null || len !== a1.length) { // not array? or not same length?
+  if (len !== a1.length) { // not array? or not same length?
     return false
   }
 
   for (i = 0; i < len; i++) {
-    if (a0[i] !== a1[i]) {
+    if (
+      a0[i] !== a1[i] &&
+      !(
+        equalities[i] &&
+        equalities[i](a0[i], a1[i])
+      )
+    ) {
       return false
     }
   }