function taskProcessor(params, isTX) {

            if (typeof params.cb !== 'function') {
                return $p.reject(new TypeError('Callback function is required.'));
            }

            if (params.options.reusable) {
                return config.$npm.task.callback(obj.ctx, obj, params.cb, config);
            }

            const taskCtx = ctx.clone(); // task context object;
            if (isTX) {
                taskCtx.txLevel = taskCtx.txLevel >= 0 ? (taskCtx.txLevel + 1) : 0;
            }
            taskCtx.inTransaction = taskCtx.txLevel >= 0;
            taskCtx.level = taskCtx.level >= 0 ? (taskCtx.level + 1) : 0;
            taskCtx.cb = params.cb; // callback function;
            taskCtx.mode = params.options.mode; // transaction mode;
            if (this !== obj) {
                taskCtx.context = this; // calling context object;
            }

            const tsk = new config.$npm.task.Task(taskCtx, params.options.tag, isTX, config);
            taskCtx.taskCtx = tsk.ctx;
            extend(taskCtx, tsk);

            if (taskCtx.db) {
                // reuse existing connection;
                npm.utils.addReadProp(tsk.ctx, 'useCount', taskCtx.db.useCount);
                addServerVersion(tsk.ctx, taskCtx.db.client);
                return config.$npm.task.execute(taskCtx, tsk, isTX, config);
            }

            // connection required;
            return config.$npm.connect.pool(taskCtx, dbThis)
                .then(db => {
                    taskCtx.connect(db);
                    npm.utils.addReadProp(tsk.ctx, 'useCount', db.useCount);
                    addServerVersion(tsk.ctx, db.client);
                    return config.$npm.task.execute(taskCtx, tsk, isTX, config);
                })
                .then(data => {
                    taskCtx.disconnect();
                    return data;
                })
                .catch(error => {
                    taskCtx.disconnect();
                    return $p.reject(error);
                });
        }
@method Database#txIf
@description
Executes a conditional transaction that results in an actual transaction ({@link Database#tx tx}), if the condition is met,
or else it executes a regular {@link Database#task task}.

The default condition is `not in transaction`, to start a transaction only if currently not in transaction,
or else start a task, which is the same as calling the following:

```js
db.txIf({cnd: t => !t.ctx || !t.ctx.inTransaction}, cb => {})
```

It is useful when you want to avoid $[Nested Transactions] - savepoints.

@param {string|number|Object} [options]
This parameter is optional, and presumed skipped when the first parameter is a function (`cb` parameter).

When it is of type `string` or `number`, it is assumed to be option `tag` passed in directly. Otherwise,
it is expected to be an object with options as listed below.

@param {} [options.tag]
Traceable context for the task/transaction (see $[tags]).

@param {txMode.TransactionMode} [options.mode]
Transaction Configuration Mode - extends the transaction-opening command with additional configuration.

@param {boolean|function} [options.cnd]
Condition for opening a transaction ({@link Database#tx tx}), if it is met, or a {@link Database#task task} when the condition is not met.
It can be either a simple boolean, or a callback function that takes the task/tx context as `this` and as the first parameter.

Default condition (when it is not specified):

```js
{cnd: t => !t.ctx || !t.ctx.inTransaction}
```

@param {boolean|function} [options.reusable=false]
When `cnd` is/returns false, reuse context of the current task/transaction, if one exists.
It can be either a simple boolean, or a callback function that takes the task/tx context as `this`
and as the first parameter.

By default, when `cnd` is/returns false, the method creates a new task. This option tells
the method to reuse the current task/transaction context, and not create a new task.

This option is ignored when executing against the top level of the protocol, because on
that level, if no transaction is suddenly needed, a new task becomes necessary.

@param {function} cb
Transaction/task callback function, to return the result that will determine either
success or failure for the operation.

The function can be either the first or the second parameter passed into the method.

It also can be an ES7 `async` function.

@returns {external:Promise}
A promise object with the result from the callback function.

@see
{@link Task},
{@link Database#task Database.task},
{@link Database#taskIf Database.taskIf},
{@link Database#tx Database.tx},
{@link TaskContext}