formily/reactive

385 阅读1分钟

Tracker

reactive-react里面的hook,new了Tacker,其属性有track(view)

export default class Tracker {
        constructor(scheduler_){
        this.scheduler = scheduler_
    }
    track = (tracker) => {
        //tracker:函数组件
        this.results = tracker()
        return this.results
    }

    dispose = () => {

    }
}

observable

接收对象,get收集依赖,set执行依赖

import {
  bindTargetKeyCurrentReaction,
  runReactionsFormTargetKey,
} from "./reaction";

const basHandlers = {
  get(target, key) {
    const result = target[key];
    //收集当前依赖(reaction)
    bindTargetKeyCurrentReaction({ target, key });
    return result;
  },
  set(target, key, value) {
    target[key] = value;
    //执行全部依赖(reactions)
    runReactionsFormTargetKey({target,key,value});
    return true;
  },
};

export default function observable(target) {
  //定义proxy,get某个值的时候收集依赖,set的时候执行依赖函数
  const proxy = new Proxy(target, basHandlers);

  return proxy;
}

收集当前依赖 用reactionStack栈来收集,在调用tarck的时候存进去

//接收依赖
export function bindTargetKeyCurrentReaction({target,key}){
    //获取当前的依赖
    const current = ReactionsStack[ReactionsStack.length - 1]
    if(current){
        addRawReactionsMap(target,key,current)
    }
}

保存依赖

export const RawReactionsMap = new WeakMap()
export class ArraySet{
    constructor(value_ = []){
        this.value = value_
    }

    add(item){
        if(!this.has(item)){
            this.value.push(item)
        }
    }

    has(item){
        return this.value.indexOf(item) > -1
    }
}
//  建立reaction「page」和target「count」的联系
function addRawReactionsMap(targe,key,reaction) {
   let reactionsMap = RawReactionsMap.get(targe)
   if(reactionsMap){
    const reactions = reactionsMap.get(key)
    if(reactions){
        reactions.add(reaction)
    }else{
        reactions.set(key,new ArraySet([reaction]))
    }
   }else{
    reactionsMap = new Map([[key,new ArraySet([reaction])]])
    RawReactionsMap.set(targe,reactionsMap)
   }

   return reactionsMap
}

执行依赖

//执行依赖
export function runReactionsFormTargetKey({target,key,value}){
   const reactions = []
   const reactionsMap = RawReactionsMap.get(target)
   if(reactionsMap){
    const map = (reactionsMap.get(key)).value
    map.forEach(i => {
        reactions.push(i)
    })
   }
   for(let i = 0;i<reactions.length;i++){
    console.log('reactions:',reactions);
    const reaction = reactions[i]
    //scheduler:fouceupdate()
    if(typeof reaction.scheduler == 'function'){
        reaction.scheduler()
    }
   }
}