如何将函数链接与异步函数一起使用?

时间:2019-03-29 08:22:05

标签: javascript class object asynchronous async-await

我目前正在编写e2e测试,我想创建一些类来为我抽象某些异步任务。最后,我想实例化一个对象,让我们链接异步函数。假设我有一个Walker,可让我浏览页面。我想以这种方式使用它:

const walker = new Walker(t)

await walker
  .goToMainPage()
  .goToProfile()

目前,我只能这样使用它:

const walker = new Walker(t)

await walker.goToMainPage()
await walker.goToProfile()

这是我当前实现Walker Class的粗略实现。 t和object的位置允许我在浏览器中执行异步操作。

class Walker {
  constructor(t) {
    this.t = t;
  }
  async goToMainPage () {
    await t.goTo('url/main')
    return this
  }
  async goToProfile () {
    await t.goTo('url/Profile')
    return this
  }
}

关于如何创建异步可链接函数调用的任何想法?

2 个答案:

答案 0 :(得分:4)

await不仅适用于Promises,而且适用于每个提供.then处理程序的对象……因此,您的Walker可以实现.then方法以允许等待:

 class Walker {
   constructor(t) {
     this.t = t;
     // set up a task queue for chaining
     this.task = Promise.resolve();
    }

    // shedules a callback into the task queue
    doTask(cb) {
       // TODO: error handling
       return this.task = this.task.then(cb);
    }

    // allows to use this like a promise, e.g. "await walker";
    then(cb) { cb(this.task); }

    goToMainPage () {
      this.doTask(async () => { // shedule to chain
        await t.goTo('url/main')
      });
      return this; // return walker for chaining
   }

 }

您可以这样做:

 await walker.goToMainPage();
 await walker.goToMainPage().goToMainPage();

如果您从doTask内部返回内容,则await对其进行处理将解决该问题:

 returnStuff() {
   this.doTask(() => "stuff");
   return this;
 }

 //...
 console.log(await walker.returnStuff()); // "stuff"
 console.log(await walker.returnStuff().goToMainPage()); // undefined, result gets lost

Have fun with it!

答案 1 :(得分:2)

您正在使用async/await-本质上它是Promise链的替代品(Promise本身就是回调地狱的解决方案)。如果您真的要使用链接:

walker().then(w => w.goToMainPage()).then(w => w.goToProfile());