ReactReconcileTransaction

之前简要介绍过React中的事务机制,https://www.hoyt-tian.com/reactzhong-de-transaction/ 。事务机制渗透在React的更新操作中,这里再更详细的解析一下。

Transaction

React源代码中跟事务相关的核心文件有两个,一个是src/core/ReactReconcileTransaction.js,另一个是src/utils/Transaction.js;其中Transaction.js中以Mixin的形式定义了事务接口的4个核心方法,分别是reinitializeTransaction,perform,initializeAll,closeAll,除此之外还有几个辅助函数,其中perform方法包含了整个事务流程,reinitializeTransaction用来重复利用缓冲池中的transaction对象,将之进行重新初始化。perform的代码截取出来如下:


 perform: function(method, scope, a, b, c, d, e, f) {
   // _isInTransaction标记了当前事务的状态
    throwIf(this.isInTransaction(), DUAL_TRANSACTION);
    var memberStart = Date.now();
    var err = null;
    var ret;
    try {
      // 初始化所有事务执行之前的锁
      this.initializeAll();
      // 被添加到事务中执行的函数,不能超过5个参数,因为源码中忽略了后续的参数
      ret = method.call(scope, a, b, c, d, e, f);
    } catch (ie_requires_catch) {
      err = ie_requires_catch;
    } finally {
      var memberEnd = Date.now();
      this.methodInvocationTime += (memberEnd - memberStart);
      try {
        // 事务执行成功之后,释放锁
        this.closeAll();
      } catch (closeAllErr) {
        err = err || closeAllErr;
      }
    }
    if (err) {
      throw err;
    }
    return ret;
  }

很显然,React中的事务概念是继承自数据库中的概念,但是,React是模拟的实现。所谓的事务锁,其实就是一个对象,包含两个方法:initialize和close。在事务执行initializeAll时,所有锁的inititalize方法会被按顺序调用;而当事务执行完毕之后,closeAll方法又会执行所有的close方法,按照加锁的顺序。

ReactReconcileTransaction

ReactReconcileTransaction中定义了3个默认事务锁,它们是

  • SELECTION_RESTORATION
  • EVENT_SUPPRESSION
  • ON_DOM_READY_QUEUEING

其中SELECTION_RESTORATION用来保存当前光标选区信息,以保证更新后的选区信息仍然正确。其initialize和close方法分别对应了ReactInputSelection中的getSelectionInformation和restoreSelection

而EVENT_SUPPRESSION,会在事务实际执行前暂停所有的顶层事件监听,在执行完毕后再重新开启监听。

剩下的ON_DOM_READY_QUEUEING,它在执行close时,会通知所有监听了onDOMReady的listeners(比如componentDidMount和componentDidUpdate,如果定义了,就会通过下面的代码注入到事务的事件处理队列中


transaction.getReactOnDOMReady().enqueue(this, this.componentDidMount);

更多关于DOMReady的事件监听处理代码,则集中在src/core/ReactOnDOMReady.js中。

事务锁阶段间的数据传递

虽然事务锁被划分成了初始化和关闭两个阶段,但偶尔还是会出现两个阶段的数据共享需求。比如EVENT_SUPPRESSION,在初始化时,需要将所有事件监听关闭,但close时需要还原到初始值,而这个初始状态,既可能是开启监听状态,也可能是关闭监听状态。类似这样的需求,就需要在锁的两个阶段进行数据传递。

React通过wrapperInitData数组,保存了每个wrapper初始化时的执行返回结果,在close时,从数组中取出,作为参数传递给wrapper的close函数,从而实现了数据传递。

alt

Show Comments

Get the latest posts delivered right to your inbox.