code: function(task, recurse) {
    // get time since last context swap (ms), if enough time has passed set
    // swap to true to indicate that doNext was performed asynchronously
    // also, if recurse is too high do asynchronously
    var swap =
      (recurse > sMaxRecursions) ||
      (+new Date() - task.swapTime) > sTimeSlice;
  
    var doNext = function(recurse) {
      recurse++;
      if(task.state === RUNNING) {
        if(swap) {
          // update swap time
          task.swapTime = +new Date();
        }
  
        if(task.subtasks.length > 0) {
          // run next subtask
          var subtask = task.subtasks.shift();
          subtask.error = task.error;
          subtask.swapTime = task.swapTime;
          subtask.userData = task.userData;
          subtask.run(subtask);
          if(!subtask.error)
          {
             runNext(subtask, recurse);
          }
        } else {
          finish(task);
  
          if(!task.error) {
            // chain back up and run parent
            if(task.parent !== null) {
              // propagate task info
              task.parent.error = task.error;
              task.parent.swapTime = task.swapTime;
              task.parent.userData = task.userData;
  
              // no subtasks left, call run next subtask on parent
              runNext(task.parent, recurse);
            }
          }
        }
      }
    };
  
    if(swap) {
      // we're swapping, so run asynchronously
      setTimeout(doNext, 0);
    } else {
      // not swapping, so run synchronously
      doNext(recurse);
    }
  }
docs: Run the next subtask or finish this task.
  
  @param task the task to process.
  @param recurse the recursion count.