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;