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

Javascript 如何将函数链接与异步函数一起使用?,javascript,class,object,asynchronous,async-await,Javascript,Class,Object,Asynchronous,Async Await,我目前正在编写一个e2e测试,我想创建一些类来为我抽象某些异步任务。最后,我想实例化一个对象,让我来链接异步函数。假设我有一个Walker,让我在页面中导航。我想这样使用它: const walker=新walker(t) 等待步行者 .goToMainPage() .goToProfile() 目前我只能这样使用它: const walker=新walker(t) wait walker.goToMainPage() wait walker.goToProfile() 这是我目前如何实现W

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

const walker=新walker(t)
等待步行者
.goToMainPage()
.goToProfile()
目前我只能这样使用它:

const walker=新walker(t)
wait walker.goToMainPage()
wait walker.goToProfile()
这是我目前如何实现Walker类的一个粗略实现。其中
t
是一个对象,允许我在浏览器中执行异步操作

class Walker{
建造师(t){
t=t;
}
异步goToMainPage(){
等待t.goTo('url/main')
还这个
}
异步goToProfile(){
等待t.goTo('url/Profile')
还这个
}
}

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

您使用的是
async/await
——它本质上是承诺链接的替代品(承诺本身就是回调地狱的解决方案)。如果您真的想使用链接:

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

await
不仅适用于承诺,而且适用于提供
处理程序的每个对象。。。因此,您的Walker可以实现一个
。然后
方法来允许等待:

 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
内部返回某个内容,
wait
ing将解析为:

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

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

我确实明白了,但我想使用上面提到的语法。我知道,如果以某种方式构建对象/类,就有可能获得这种语法。我目前使用的e2e测试库(Testcafe)允许使用这种语法。因此,必须有一种方法来实现这种对象结构。这是一个非常简洁的解决方案。基本上,我们将所有承诺委托给其他人,直到某个代码调用我们的
。然后
处理程序。对于OP的示例代码,
.then()
将由
wait
调用。整洁的我在代码笔中尝试了这段代码,然后
返回这段代码
仅返回
Walker{t:undefined}
,只返回
t
,不返回两个方法
goToMainPage
goToProfile
。我对此有点困惑。为什么方法不是实例化类的一部分?有人能解释吗?杰里米,因为他们是原型的一部分
Walker{…}
告诉您有关继承的信息…@JeremyThille应该正常工作的不是代码,更像sudo代码。我稍微更新了这个例子。在类的实例化过程中,我们需要传递
t
对象,例如
newwalker(t)
。t来自我正在使用的另一个库。你可以把它想象成一个对象,它提供了一系列异步功能。@Jonaswillms那么,类的方法只是原型的一部分,而不是类本身的一部分吗?那是weird@jeremy嗯
new Walker
仍然是一个实例,这就是
这个
所指向的。是的,只有
static
方法是构造函数本身的一部分,方法是原型的一部分。记住:
只是构造器周围的语法糖。