In the source code of commandStack
, I found that when executing the execute(command, context)
method, _poshAction(action)
is executed to store the action object into _currentExecution
.
Then, _internalExecute(action)
is executed. But in the _internalExecute
method, _poshAction(action)
and _popAction()
are still executed once, and the effect of the two _poshAction(action)
looks the same, so why is it necessary to handle it this way?
CommandStack.prototype.execute = function(command, context) {
if (!command) {
throw new Error('command required');
}
this._currentExecution.trigger = 'execute';
const action = { command: command, context: context };
this._pushAction(action);
this._internalExecute(action);
this._popAction();
};
CommandStack.prototype._pushAction = function(action) {
const execution = this._currentExecution,
actions = execution.actions;
const baseAction = actions[0];
if (execution.atomic) {
throw new Error('illegal invocation in <execute> or <revert> phase (action: ' + action.command + ')');
}
if (!action.id) {
action.id = (baseAction && baseAction.id) || this._createId();
}
actions.push(action);
};
CommandStack.prototype._internalExecute = function(action, redo) {
const command = action.command,
context = action.context;
const handler = this._getHandler(command);
if (!handler) {
throw new Error('no command handler registered for <' + command + '>');
}
this._pushAction(action);
if (!redo) {
this._fire(command, 'preExecute', action);
if (handler.preExecute) {
handler.preExecute(context);
}
this._fire(command, 'preExecuted', action);
}
// guard against illegal nested command stack invocations
this._atomicDo(() => {
this._fire(command, 'execute', action);
if (handler.execute) {
// actual execute + mark return results as dirty
this._markDirty(handler.execute(context));
}
// log to stack
this._executedAction(action, redo);
this._fire(command, 'executed', action);
});
if (!redo) {
this._fire(command, 'postExecute', action);
if (handler.postExecute) {
handler.postExecute(context);
}
this._fire(command, 'postExecuted', action);
}
this._popAction();
};
CommandStack.prototype._popAction = function() {
const execution = this._currentExecution,
trigger = execution.trigger,
actions = execution.actions,
dirty = execution.dirty;
actions.pop();
if (!actions.length) {
this._eventBus.fire('elements.changed', { elements: uniqueBy('id', dirty.reverse()) });
dirty.length = 0;
this._fire('changed', { trigger: trigger });
execution.trigger = null;
}
};