Fetch a number of jobs of certain type
@param {String} qName Queue name
@param {String} type Job type: {wait|active|delayed|completed|failed}
@param {Number} offset Index offset (optional)
@param {Number} limit Limit of the number of jobs returned (optional)
@returns {Promise} A promise that resolves to an array of jobs
function(qName, type, offset, limit) {
    var q = queue.get(qName);
    if (!(offset >= 0)) {
      offset = 0;
    }
    if (!(limit >= 0)) {
      limit = 30;
    }
    if (type === 'wait' || type === 'active') {
      return q.getJobs(type, 'LIST', offset, offset + limit - 1).then(function(jobs) {
        return Promise.all(_.map(jobs, function(job) {
          if (!job) {
            return null;
          }
          return job.getState().then(function(state) {
            job.state = state;
            return job;
          });
        }));
      });
    } else if (type === 'delayed') {
      return q.getJobs(type, 'ZSET', offset, offset + limit - 1).then(function(jobs) {
        return Promise.all(_.map(jobs, function(job) {
          if (!job) {
            return null;
          }
          return job.getState().then(function(state) {
            job.state = state;
            return job;
          });
        }));
      });
    } else if (type === 'completed' || type === 'failed') {
      var client = redis.client();
      var key = 'bull:' + qName + ':' + type;
      return client.smembersAsync(key).then(function(ids) {
        var _ids = ids.slice(offset, offset + limit);
        return Promise.all(_.map(_ids, function(id) {
          return q.getJob(id).then(function(job) {
            if (!job) {
              return null;
            }
            return job.getState().then(function(state) {
              job.state = state;
              return job;
            });
          });
        }));
      });
    }
    throw new Error('You must provide a valid job type.');
  }