我目前正在编写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
}
}
关于如何创建异步可链接函数调用的任何想法?
答案 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
答案 1 :(得分:2)
您正在使用async/await
-本质上它是Promise链的替代品(Promise本身就是回调地狱的解决方案)。如果您真的要使用链接:
walker().then(w => w.goToMainPage()).then(w => w.goToProfile());