这是我成长的道路:回调,承诺,异步/等待。我谨记一个模式-流利的构建器,对解释器来说看起来更多。我想将异步/等待与解释器混合在一起。可能吗?我觉得这是不可能的。但我可以确切地定义原因。 我有:
after(async () => {
await shellContainer.uninstall()
await shellContainer.dispose()
})
我很感兴趣:
after(async () => {
await shellContainer
.uninstall()
.dispose()
})
致谢。
答案 0 :(得分:1)
如果更改.uninstall
以返回实例(shellContainer
),同时将其Promise分配给实例的属性,并在链式调用中检索该Promise,则可以:
class ShellContainer {
uninstall() {
// Chain or construct a Promise and assign the result to a property of the instance:
this.uninstProm = new Promise((resolve, reject) => {
// do stuff
});
return this;
}
dispose() {
return this.uninstProm.then(() => {
// do stuff
});
}
}
然后
await shellContainer
.uninstall()
.dispose()
dispose
完成后将解决。
请注意,使用这种方法,单独调用uninstall
可能会导致意外行为,因为.uninsall
将同步返回实例,而不是Promise。您可能会考虑使用一个额外的参数或其他方式来表明您是否希望将uninstall
调用与其他方式链接起来,或者是否希望直接返回Promise,例如
class ShellContainer {
uninstall(doChain) {
// Chain or construct a Promise and assign the result to a property of the instance:
this.uninstProm = new Promise((resolve, reject) => {
// do stuff
});
return doChain ? this : this.uninstProm;
}
dispose() {
return this.uninstProm.then(() => {
// do stuff
});
}
}
和
await shellContainer
.uninstall(true)
.dispose()
或者只是
await shellContainer.uninstall(); // no doChain argument
但是,如果只存在一个 承诺,那么在许多情况下对await
的需求就不多了-它可能根本无法使代码更清晰。例如
after(async () => {
await shellContainer
.uninstall()
.dispose()
})
等同于
after(() => shellContainer
.uninstall()
.dispose()
);
答案 1 :(得分:1)
要分开考虑,可以引入专用的builder来实现流畅的界面。
这样,您只需要从最终的build
方法中返回一个Promise,就可以使事情变得简单得多。
以下是一个相当粗糙但实用的示例:
class ShellContainer
{
uninstall() {
return new Promise(resolve => {
setTimeout(() => {
console.log('uninstalled');
resolve();
}, 400 + Math.random() * 600);
});
}
dispose() {
return new Promise(resolve => {
setTimeout(() => {
console.log('disposed');
resolve();
}, 400 + Math.random() * 600);
});
}
}
class ShellContainerBuilder
{
container;
plan;
constructor() {
this.reset();
}
reset() {
this.container = new ShellContainer();
this.plan = () => Promise.resolve();
}
stage(op) {
this.plan = ((prev) => () => prev().then(op))(this.plan);
}
uninstall() {
this.stage(() => this.container.uninstall());
return this;
}
dispose() {
this.stage(() => this.container.dispose());
return this;
}
build() {
return this.plan().then(() => this.container);
}
}
(async () => {
console.log('starting w/o builder:');
const shellContainer1 = new ShellContainer();
await shellContainer1.uninstall();
await shellContainer1.dispose();
console.log('w/o builder done.');
console.log('starting w/ builder:');
const shellContainer2 = await (new ShellContainerBuilder()).uninstall().dispose().build();
console.log(shellContainer2);
console.log('w/ builder done.');
})();
答案 2 :(得分:0)
实现Fluent构建器的模式-解释器不适合Async / Await。因为等待是对每个操作应用的。在链的中间没有这样的语法来处理异步。要处理异步操作,您应该拆分链接并由await运算符包装操作,就像在第一个代码段中一样。