3

i have some problems with my class design and promises. I am trying to listen for a change variable by calling my promise cb recursively. And when networkResponse returns a valid (not null) token i am trying to resolve it or it will check 500 times by delaying 500 ms in each call.

Here is the my class with simplified now:

class Tokenizer {
    constructor(page) {
        this.page = page;
        this.token = null;
        this.tries = 500;
        this.page.on('response', this.onNetworkResponse.bind(this));
    }
    async onNetworkResponse(response) {
        if (condition) {
            let resp = await response.text();
            let regex = /access_token=([\w\d]+)/g;
            let _token = regex.exec(response);
            this.token = _token[1];
        }
    }

    getToken() {
        return new Promise(function cb(resolve, reject) {
            console.log(this.tries + ' remaining');
            if (--this.tries > 0 && !this.token) setTimeout(() => cb(resolve, reject), 500);
            else (this.tries <= 0) ? reject('Try') : resolve(this.token);
        });
    }
}

And I call the promise like this:

const t = new Tokenizer();

let test = async () => {
   let token = await t.getToken();
}

test();

However i am losing this scope inside of cb function. If someone can answer this problem i would really appreciate it

For whom have a problem like this i've just updated my getToken function like this:

  getToken() {
    var cb = (resolve, reject) => {
      console.log(this.tries);
      if (--this.tries > 0 && !this.token) setTimeout(() => cb(resolve, reject), 500);
      else (this.tries <= 0) ? reject('Try') : resolve(this.token);
    }
    return new Promise(cb);
  }

1 Answers1

0

You're losing scope because when you call cb from setTimeout, it changes context. You could solve that issue with an arrow function or with .bind, (this), but I'm going to suggest a slightly different approach independent of setTimeout(), I hope you find it useful for your needs:

class Tokenizer {
  constructor(page) {
    this.page = page;
    this.token = null;
    this.tries = 500;
    this.subscriber = null
    this.page.on('response', this.onNetworkResponse.bind(this));
  }
  async onNetworkResponse(response) {
    if (condition) {
      let resp = await response.text();
      let regex = /access_token=([\w\d]+)/g;
      let _token = regex.exec(response);
      this.token = _token[1];
      // Is some function waiting for the token? Call it
      if (typeof this.subscriber === 'function') {
        this.subscriber(_token[1])
        this.subscriber = null
      }
    }
  }

  getToken = () => {
    return new Promise((resolve, reject) => {
      // Is the token already available? Return it
      if (this.token) {
        resolve(this.token)
        // Token not available yet? Tell the tokenizer we are waiting for it.
      } else {
        this.subscriber(resolve)
      }
    });
  }
}
Miguel Calderón
  • 3,001
  • 1
  • 16
  • 18