如何在 javascript ES6 类 中链接异步方法

How to chain async methods in javascript ES6 classes

我想从 class 链接方法。我有同步方法的问题,但我不知道如何使用异步方法。

例如,这个 class:

class Example {

  constructor() {
    this.val = 0
  }

  async () {
    setTimeout(() => {
      this.val += 1
      return this
    }, 5000)
  }

  sync () {
    this.val += 1
    return this
  }

  check () {
    console.log('checker', this.val)
    return this
  }

}

这个有效:

new Example().sync().check()
> 1

但这行不通:

new Example().async().check()
> TypeError: Cannot read property 'check' of undefined

P.S。我想要链接,而不是地狱回调。

如果您只想 new Example().async().check() 工作,那么您需要做的就是 return this 在调用 setTimeout 之后。例如:

async () {
  setTimeout(() => {
    this.val += 1
  }, 5000)
  return this
}

超时中的 return this 不是必需的,因为它会自行执行。那时基本上 运行 是独立的。

真的,如果您希望整个事情 运行 完全异步,并且您能够控制某些事情何时发生的流程,您需要使用 promises 来实现它。

如果您正在使用 async 函数和方法,那么您就是在使用 promises(我想您知道它们,如果不知道,请在继续阅读之前了解它们)。

如果考虑等待,则不应在异步函数内部使用 setTimeout。相反,为超时创建一个承诺,最好使用这样的辅助函数:

function timeout(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    });
}

现在您可以按照自己的意愿编写方法:

class Example {
  …
  async async () {
    await timeout(5000);
    this.val += 1;
    return this;
  }
  …
}

当然,作为一个 async 函数,它不是 return 实例本身,而是对实例的承诺。如果你要链接,你将不得不在另一个异步函数中调用它,你可以在其中 await 承诺:

(async function() {
    (await (new Example().async())).check();
}());

我想你想在超时结束后调用 check()。问题是分叉了,你不能立即得到 return.

可用的东西

您可以传入 check() 作为回调:

class Example {

  constructor() {
    this.val = 0
  }

  async (callback) {
    setTimeout(() => {
      this.val += 1
      callback()
    }, 5000)
  }

  sync () {
    this.val += 1
    return this
  }

  check () {
    console.log('checker', this.val)
    return this
  }

}

// execution
var ex = new Example();
ex.async(ex.check)

...或承诺

class Example {

  constructor() {
    this.val = 0
  }

  async (callback) {
    var deferred = Q.defer()
    setTimeout(() => {
      this.val += 1
      deferred.resolve();
    }, 5000)
    return deferred.promise;
  }

  sync () {
    this.val += 1
    return this
  }

  check () {
    console.log('checker', this.val)
    return this
  }

}

// execution
var ex = new Example()
ex.async().then(() => ex.check())

...或者您可以使用 ES6 生成器

你要找的问题Promises. You'll need to likely install a polyfill, like Bluebird or q将得到最优雅的解决。

我会将您的异步方法更改为:

async() {
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            this.val += 1;
            resolve(this);
        }, 5000);
    });
}

以及您的调用代码:

new Example().async().then((instance)=>instance.check());

不幸的是,在确定 ES7 异步函数之前,如果没有某种形式的回调,将不会有一种优雅的方式来做到这一点。