我如何防止没有箭头功能的承诺丢失上下文

时间:2018-06-27 20:17:19

标签: javascript promise

我有以下代码...

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

这似乎太冗长,但是当我尝试...

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

我收到错误消息是因为在page.isLoaded的上下文中this变成了承诺。

有没有一种方法可以在以后不用箭头功能?

2 个答案:

答案 0 :(得分:1)

正确使用承诺。箭头符号没什么太冗长的,但是一个好的实践是确保向任何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(),那通常是您在确保Sope方面与JavaScript作战的标志,而不是利用JavaScript可以确保正确范围的各种方式)

答案 1 :(得分:0)

Mike一样,在找到答案后建议它似乎并不那么冗长...

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

(感谢@GetOffMyLawn)

如果有人有创造性的解决方案,我将不予回答。