code: function helperWrapper (fn, args) {
      var _this = this
      var options = args[args.length - 1]
      var hash = options.hash
  
      // "fn" and "inverse" return strings. They must be able to handle promises
      // just as the compiled template and partials
      options.fn = options.fn && wrap(options.fn, prepareAndResolveMarkers)
      options.inverse = options.inverse && wrap(options.inverse, prepareAndResolveMarkers)
  
      // If there are any promises in the helper args or in the hash,
      // the evaluation of the helper cannot start before these promises are resolved.
      var promisesInArgs = anyApplies(args, isPromiseAlike)
      var promisesInHash = anyApplies(values(hash), isPromiseAlike)
  
      if (!promisesInArgs && !promisesInHash) {
        // No promises in hash or args. Act a normal as possible.
        var result = fn.apply(_this, args)
        return isPromiseAlike(result) ? markers.asMarker(result) : result
      }
  
      var promise = deep(args).then(function (resolvedArgs) {
        // We need "markers", because we are in a new event-loop-cycle now.
        return prepareAndResolveMarkers(function () {
          return fn.apply(_this, resolvedArgs)
        })
      })
      return markers.asMarker(promise)
    }
docs: Wrapper for helper methods:
  * Call the helper after resolving parameters (if any promises are passed)
  * Wrap `options.fn` and `options.inverse` to return promises (if needed)
  * Convert helper results markers if they are promises.