async _request(options, depth, previousUrl, retryCount = 0) {
    this.emit(HCCrawler.Events.RequestStarted, options);
    const crawler = await this._newCrawler(options, depth, previousUrl);
    try {
      const res = await this._crawl(crawler);
      await crawler.close();
      this.emit(HCCrawler.Events.RequestFinished, options);
      const requested = await this._checkRequestedRedirect(options, res.response);
      await this._markRequested(options);
      await this._markRequestedRedirects(options, res.redirectChain, res.response);
      if (requested) return [];
      this._exportLine(res);
      await this._success(res);
      return res.links;
    } catch (error) {
      await crawler.close();
      extend(error, { options, depth, previousUrl });
      if (retryCount >= options.retryCount) {
        this.emit(HCCrawler.Events.RequestFailed, error);
        await this._error(error);
        return [];
      }
      this.emit(HCCrawler.Events.RequestRetried, options);
      await delay(options.retryDelay);
      return this._request(options, depth, previousUrl, retryCount + 1);
    }
  }
@param {!Object} options
@param {!number} depth
@param {string} previousUrl
@param {!number=} retryCount
@return {!Promise<!Array<!string>>}
@private