失去Promise内部的范围

时间:2018-02-26 08:20:05

标签: scope promise async-await es6-class puppeteer

我的班级设计和承诺有些问题。我试图通过递归调用我的promise cb来监听变量变量。当networkResponse返回有效(非空)令牌时,我正在尝试解决它,或者它将通过在每次调用中延迟500毫秒来检查500次。

这是我的课程,简化现在:

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);
        });
    }
}

我称之为这样的承诺:

const t = new Tokenizer();

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

test();

但是我在cb函数中失去了这个范围。如果有人能回答这个问题,我会非常感激

对于有这样问题的人,我刚刚更新了我的getToken函数:

  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 个答案:

答案 0 :(得分:0)

您失去了范围,因为当您从cb致电setTimeout时,它会更改背景。您可以使用箭头功能或使用.bind, (this)解决该问题,但我建议采用与setTimeout()无关的略有不同的方法,我希望您发现它对您的需求有用:

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)
      }
    });
  }
}