React的批处理策略

789 阅读2分钟

ReactDefaultBatchingStrategy模块

批处理策略也就是我们的 ReactDefaultBatchingStrategy 模块。

    <!--
        以下便是整个模块的代码,很简单,分别是:
        
    -->
    
    <!--
        两个Wrapper,为 ReactDefaultBatchingStrategyTransaction 事物使用。
    -->
    var RESET_BATCHED_UPDATES = {
      initialize: emptyFunction,
      close: function () {
        ReactDefaultBatchingStrategy.isBatchingUpdates = false;
      }
    };
    
    var FLUSH_BATCHED_UPDATES = {
      initialize: emptyFunction,
      close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates)
    };
    
    var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];
    
    <!--
        定义使用的事物
    -->
    function ReactDefaultBatchingStrategyTransaction() {
      this.reinitializeTransaction();
    }
    
    <!--
        这里是 ReactDefaultBatchingStrategyTransaction事物继承 基类 Transaction 类。
    -->
    assign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction.Mixin, {
      getTransactionWrappers: function () {
        return TRANSACTION_WRAPPERS;
      }
    });
    
    var transaction = new ReactDefaultBatchingStrategyTransaction();
    
    <!--
        这里是定义了策略的核心。
        而这个批处理策略的核心是 一个属性 isBatchingUpdates 表示当前是否正住处与批处理中。
    -->
    var ReactDefaultBatchingStrategy = {
      isBatchingUpdates: false,
      
      batchedUpdates: function (callback, a, b, c, d, e) {
        var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
    
        ReactDefaultBatchingStrategy.isBatchingUpdates = true;
    
    
    
        
        if (alreadyBatchingUpdates) {
          <!--
            如果当前事务正在更新过程在中,则调用callback,既enqueueUpdate,比如setState方法的
          -->
          callback(a, b, c, d, e);
        } else {
          <!--
            否则的话就启用事物机制,执行callback。也就是那些不需要启用批处理策略的东西。
            比如:ReactEventListener的dispatchEvent方法。
            
            事物会在callback执行完毕的时候,将isBatchingUpdates初始化为false。
          -->
          transaction.perform(callback, null, a, b, c, d, e);
        }
      }
    };
    
    module.exports = ReactDefaultBatchingStrategy;

batchingStrategy是以单例的形式存在,为的就是为setState这样的操作提供唯一的一个操作环境。避免不必要的更新。 也就是 batchingStrategy.isBatchingUpdates 这个属性。

如果 batchingStrategy.isBatchingUpdates属性为true则表示走批量更新的分支,将所有的操作,比如多个setState都放在队列里,等同步的代码执行完毕的之后,合并这个队列并执行。比如多个setState,最后只会执行一次。比如

    <!--
        假设一个click方法,中写了三次setState操作,最后只会执行最后一次,也就是count会被变为1234.
        这里,React会将他们进行一次对象的合并,类似于assign方法,同等属性的后边会覆盖前边的,这便是批处理的方式。
        
        需要注意的一点是,批处理的时候 ReactDefaultBatchingStrategy 模块里的 isBatchingUpdates 属性变为true。
    -->
    this.setState({
      count:12
    })
    this.setState({
      count:123
    })
    this.setState({
      count:1234
    })

setState

看看setState是如何使用批处理策略的。

未完待续 to be continue.