Here an example how the waiting for AJAX requests can be done with nightwatch custom commands.
One command to init the counter. on every send if will increase the counter and on ever open it will decrease it customCommands/initAjaxCounters.js:
exports.command = function () {
  this.execute(function () {
    window.sumStartedAjaxRequests = 0
    window.activeAjaxCount = 0
    function isAllXhrComplete () {
      window.activeAjaxCount--
    }
    (function (open) {
      XMLHttpRequest.prototype.open = function () {
        this.addEventListener('loadend', isAllXhrComplete)
        return open.apply(this, arguments)
      }
    })(XMLHttpRequest.prototype.open)
  })
  this.execute(function () {
    (function (send) {
      XMLHttpRequest.prototype.send = function () {
        window.activeAjaxCount++
        window.sumStartedAjaxRequests++
        return send.apply(this, arguments)
      }
    })(XMLHttpRequest.prototype.send)
  })
  return this
}
and then an other custom command to wait 
const sleepWhenOutstandingAjaxCalls = function (result) {
  if (result.value > 0) {
    this.pause(this.globals.waitForConditionPollInterval)
    this.waitForOutstandingAjaxCalls()
  }
}
exports.command = function () {
  // init the ajax counter if it hasn't been initialized yet
  this.execute('return (typeof window.activeAjaxCount === "undefined")', [], function (result) {
    if (result.value === true) {
      throw Error('checking outstanding Ajax calls will not work without calling initAjaxCounter() first')
    }
  })
  this.execute(
    'return window.activeAjaxCount', [], sleepWhenOutstandingAjaxCalls
  )
  return this
}