code: function execTask(proc, taskObj) {
    const { tasks, logger, model, sharedModel, config, logic } = proc;
    const { task, executor, notifyCmd, successCmd, failCmd,
      customArgs, execEvery, customExecId, id: taskId } = taskObj;
  
    // If not in multi-thread mode or just need to cancel a tak –
    // cancel all running task with same identifier (command id)
    if (taskObj.cancelTask || !execEvery) {
      cancelTask(proc, taskId);
      if (taskObj.cancelTask) return;
    }
  
    // Define next execution id
    const execId = customExecId || nextId();
    const executions = tasks[taskId] = tasks[taskId] || {};
    const cleanup = () => delete executions[execId];
  
    // Do not create any new task if the task with given exec id
    // already exists. Usefull for throttle/debounce tasks
    if (executions[execId]) {
      executions[execId].exec(taskObj);
    } else {
      const taskCall = executor(proc, taskObj);
      executions[execId] = taskCall;
      taskCall.exec(taskObj).then(cleanup, cleanup);
    }
  }
docs: Execute given task object in scope of given Process.
  Returns a Promise which will be resolved when task will
  be resolved or reject with with a command, which should
  be executed next.
  
  @private
  @param  {Process} proc
  @param  {Task} taskObj
  @return {Promise}