async run(generatorFunc, ctx, ...fnArgs) {
    this._running = true
    const generatorObj = generatorFunc.call(ctx, ...fnArgs)
    const response = await new Promise(async (resolve, reject) => {
      this._rejectWithinRun = (rejectValue) => {
        reject(rejectValue)
      }
      let _response;
      try {
        _response = await this._runGenerator(generatorObj)
      } catch (err) {
        reject(err)
        return;
      }
      resolve(_response)
    })
    this._interrupt = false
    this._running = false
    return response
  }
@returns a Promise that resolves when the generator function has been
executed to completion, or when it has been interrupted. It will reject if
the generator function throws an error at any point.