batchedUpdates与事务

目前为止一些准备工作已经就绪,接下来我们将进入渲染阶段的处理。

文件依然是 src/renderers/dom/client/ReactMount.js,根据前一小节,我们可以知道根节点的DOMComponent 对象或者 ReactCompositeComponent 对象创建成功,接着会调用 ReactUpdates.batchedUpdates ,这是一个批量更新的方法,我们可以在源文件中进一步阅读。

batchingStrategy.batchedUpdates(callback, a, b, c, d, e);

源文件中只不过是继续调用了一下另外一个 batchedUpdates 方法,这个方法你可以在 src/renderers/shared/reconciler/ReactDefaultBatchingStrategy.js 中阅读,整个代码量并不多,一个 isBatchingUpdates 布尔值变量以及一个 batchedUpdates 方法:

var ReactDefaultBatchingStrategy = {
  isBatchingUpdates: false,
  batchedUpdates: function(callback, a, b, c, d, e) {
    var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
    ReactDefaultBatchingStrategy.isBatchingUpdates = true;
    if (alreadyBatchingUpdates) {
      callback(a, b, c, d, e);
    } else {
      transaction.perform(callback, null, a, b, c, d, e);
    }
  },
};

很明显初始化时的 alreadyBatchingUpdates 是一个 false ,于是我们进入了 transaction.perform,而这个callback则传入了定义在 ReactMount.js 中的 batchedMountComponentIntoNode 函数,恰好这个函数中也定义了一个 transaction.perform 传入的是 mountComponentIntoNode 函数,如果你从这跟进去之后你会发现真实的DOM节点是从 ReactReconciler.mountComponent 中return而来,它存储在node节点中,巧妙的是最后添加到浏览器中使用的是insertBefore,这说明React不是将DOM做为字符串处理的而是真实的 document.createElement 创建的DOM对象。

Transaction

一路下来我们发现了很多 transaction.perform 的调用,那么它又是什么呢?

源码中的这张图很形象的说明了 Transaction 的作用,整个过程从perform开始会调用 initialize 方法,中间也许会处理很多其它方法,最后到调用close方法结束。对于 React 来说 Transaction 到底有什么作用呢?其实从初始化开始如何转化为真实的DOM元素这一个步骤中间,我们就能看到有非常多的 transaction.perform 的调用。

事务一般来说在数据库操作时非常常见,这个设计模式目标是在于并发访问多个构件之间共享的数据,它只是一个执行单元。那如果在 React 中,我们该如何理解这个设计呢?

实际上React是封装了一个Mixin来处理Transaction的,事务给需要执行的函数包装了两个wrapper,每个wrapper都有 initialize 和 close 方法。当一个事务需要 perform 的时候,都会先调用相应的 initialize 方法,同样的在事务结束的时候会调用 close 方法,这样才会构成了一个完整的事务。

通过调用栈,我们可以很清楚的知道(这里不涉及setState,因为这是初始化。)React 将渲染的处理包装成了事务,通过这个事务来处理的比如计算props,生成DOM节点等。

results matching ""

    No results matching ""