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

Dom*_*nik 3 javascript asynchronous class object async-await

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

const walker = new Walker(t)

await walker
  .goToMainPage()
  .goToProfile()
Run Code Online (Sandbox Code Playgroud)

目前我只能这样使用它:

const walker = new Walker(t)

await walker.goToMainPage()
await walker.goToProfile()
Run Code Online (Sandbox Code Playgroud)

这是我目前如何实现我的 Walker 类的粗略实现。Where tis 和 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
  }
}
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*lms 5

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
   }

 }
Run Code Online (Sandbox Code Playgroud)

这允许您执行以下操作:

 await walker.goToMainPage();
 await walker.goToMainPage().goToMainPage();
Run Code Online (Sandbox Code Playgroud)

如果您从 inside 返回某些内容doTaskawait它将解析为:

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

 //...
 console.log(await walker.returnStuff()); // "stuff"
 console.log(await walker.returnStuff().goToMainPage()); // undefined, result gets lost
Run Code Online (Sandbox Code Playgroud)

玩得开心!