Как предотвратить потерю контекста обещаний без функции стрелки - PullRequest
0 голосов
/ 27 июня 2018

У меня есть следующий код ...

page.goToPage().then(() => page.isLoaded()).then(() => driver.quit());

Это кажется слишком многословным, но когда я пытаюсь ...

page.goToPage().then(page.isLoaded).then(driver.quit);

Я получаю ошибки, потому что в page.isLoaded контекст this меняется на обещание.

Есть ли способ сделать позже без функции стрелки?

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Используйте обещания правильно. В обозначениях стрелок нет ничего слишком многословного, но хорошей практикой является обеспечение того, чтобы любой обработчик then получал информацию, необходимую ему для выполнения работы, которая вам необходима.

class Driver {
  quit() {
    console.log("quit");
  }
}

class Page {
  constructor() {
    this.driver = new Driver();
  }

  goToPage() {
    console.log("gotopage");
    return new Promise((resolve, reject) => {
      // Things happen here. If they go wrong, you call reject() with an argument that
      // is a useful error object. If they succeed, you call resolve() with data that the
      // next handler should be working with. In this case I'm passing "this" so that the
      // page is available to the next link in the chain.
      resolve(this);
    });
  }

  waitForLoad() {
    console.log("waitforload");
    return new Promise((resolve, reject) => {
      // let's have this fail half the time, for demonstration purposes.
      var l = Math.random();
      if (l < 0.5) {
        resolve(this.driver);
      } else {
        reject(new Error("error"));
      }
    });
  }
}

Теперь у вас есть правильный код с обещанием:

var p = new Page();

p.goToPage()
 .then( page => page.waitForLoad())
 .then( driver => driver.quit())
 .catch( e => console.error(e));

Каждый обработчик then теперь получает именно тот ввод, который ему необходим для вызова функций, которые ему нужно вызывать, не пытаясь прорваться через собственную область видимости и не .bind() ничего.

(Если вам нужен .bind() в обычном коде, это, как правило, признак того, что вы боретесь с JavaScript с точки зрения обеспечения удобства, а не использования различных способов, с помощью которых JavaScript позволяет вам обеспечить правильную область действия)

0 голосов
/ 27 июня 2018

Как Майк предложил после нахождения ответа, он не кажется более многословным ...

page.goToPage()
    .then(page.isLoaded.bind(page))
    .then(driver.quit.bind(driver));

(Спасибо @GetOffMyLawn)

Я оставлю вопрос без ответа, если у кого-то есть творческое решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...