Transaction source code

The Transaction module is used to implement the function of calling a specific hook function before and after the execution of the method function when an instance of a constructor calls the perform(method, args) method. The paired pre-hook initialize function and post-hook close function are added in the form of an array, and the pre-hook initialize function is used to provide parameters to the post-hook close function, which is called before the method function; post-hook close is after the method function. transfer.

The constructor needs to inherit from the prototype of Transaction, or the prototype method assigns values ​​one by one. And the getTransactionWrappers method is used to add pre-hook and post-hook; the reinitializeTransaction method is called during initialization to clear the pre- and post-hook; the perform method actually executes the method function and the front and rear hooks.

 

'use strict';

var _prodInvariant = require('./reactProdInvariant');// Production environment React form with url error

// invariant(condition,format,a,b,c,d,e,f) condition is negative, replace "%s" in format, and throw error
var invariant = require('fbjs/lib/invariant');

var OBSERVED_ERROR = {};

// Used to add the pre-hook initialize and post-hook close before and after the execution of a function method. The meaning of the pre-hook is to provide parameters to the post-hook
// Assign the reinitializeTransaction, getTransactionWrappers, and perform methods to an instance of a constructor through prototype inheritance or prototype method assignment
// The reinitializeTransaction method is executed when the instance is initialized
// The getTransactionWrappers method is used to add pre and post hooks, and the return value is in the form of [{initialize:function(){},close:function(){}}]
// The perform(method,args) method triggers the sequential execution of the pre-hook initialize, method(args), and post-hook close
var TransactionImpl = {
  // initialize
  reinitializeTransaction: function () {
    // Add the pre-hook and post-hook transactionWrapper to this.transactionWrappers
    this.transactionWrappers = this.getTransactionWrappers();

    // Initialize the parameters of the post-hook close method, which is composed of the return value of the pre-hook initialize method
    if (this.wrapperInitData) {
      this.wrapperInitData.length = 0;
    } else {
      this.wrapperInitData = [];
    }

    this._isInTransaction = false;
  },

  _isInTransaction: false,

  // Pre-hook and post-hook for adding method methods transactionWrapper={initialize:function(){},close:function(){}}
  // The pre-hook initialize method provides parameters for the post-hook close method and is stored in this.wrapperInitData
  // The return value is like [{initialize:function(){},close:function(){}}]
  getTransactionWrappers: null,

  // Determine whether the perform method is executed or not, so whether the breakpoint closeAll method is an external call or an internal call (external calls are not allowed)
  isInTransaction: function () {
    return !!this._isInTransaction;
  },

  // External interface, execute each pre-hook initialize method, then execute the method function, and finally execute the post-hook close method
  perform: function (method, scope, a, b, c, d, e, f) {
    // The perform method of the instance can only execute one at a time
    !!this.isInTransaction() ?
      process.env.NODE_ENV !== 'production' ?
        invariant(false, 'Transaction.perform(...): '
          + 'Cannot initialize a transaction when there is already an outstanding transaction.')
        : _prodInvariant ('27 '): void 0;

    var errorThrown;
    was right;
    try {
      this._isInTransaction = true;// perform method execution flag
      errorThrown = true;
      this.initializeAll(0);
      ret = method.call(scope, a, b, c, d, e, f);
      errorThrown = false;
    } finally {
      try {
        if (errorThrown) {
          // The method function reports an error and captures the error of the post-hook
          try {
            this.closeAll(0);
          } catch (err) {}
        } else {
          // The method function does not report an error, and the post-hook reports an error normally
          this.closeAll(0);
        }
      } finally {
        this._isInTransaction = false;
      }
    }
    return ret;
  },

  // Internal call, call the initialize method in the pre-hook transactionWrapper before the method function is executed
  initializeAll: function (startIndex) {
    var transactionWrappers = this.transactionWrappers;
    for (var i = startIndex; i < transactionWrappers.length; i++) {
      var wrapper = transactionWrappers[i];
      try {
        this.wrapperInitData[i] = OBSERVED_ERROR;
        this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null;
      } finally {
        // skip the line if an error is reported
        if (this.wrapperInitData[i] === OBSERVED_ERROR) {
          try {
            this.initializeAll(i + 1);
          } catch (err) {}
        }
      }
    }
  },

  // Internal call, after the method function is executed, call the initialize method in the post hook transactionWrapper
  closeAll: function (startIndex) {
    // An error is reported when the external direct call is made, which must be executed by the perform method call
    !this.isInTransaction() ?
      process.env.NODE_ENV !== 'production' ?
        invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.')
        : _prodInvariant ('28 '): void 0;

    var transactionWrappers = this.transactionWrappers;
    for (var i = startIndex; i < transactionWrappers.length; i++) {
      var wrapper = transactionWrappers[i];
      var initData = this.wrapperInitData[i];// pre-hook return value
      var errorThrown;
      try {
        errorThrown = true;
        if (initData !== OBSERVED_ERROR && wrapper.close) {
          wrapper.close.call(this, initData);
        }
        errorThrown = false;
      } finally {
        // skip the line if an error is reported
        if (errorThrown) {
          try {
            this.closeAll(i + 1);
          } catch (e) {}
        }
      }
    }

    // Clear the parameters provided to the post hook close method
    this.wrapperInitData.length = 0;
  }
};

module.exports = TransactionImpl;

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327033706&siteId=291194637