打字稿async / await结构问题

时间:2016-06-18 13:52:06

标签: typescript async-await es6-promise

我一直在处理我的Typescript项目中的一个有趣的问题(针对es6)。基本上,我希望能够以某种不确定的顺序快速定义许多不同系列的用户输入“页面”,并且前一页的结果可能会或可能不会对下一个“页面”的构造产生影响。

因此,我将每个页面视为由函数(此处为getPromise1()等)构造的Promise,一旦用户输入完成,该函数将解析为结果。然后我使用async / await按顺序创建页面。

async process() {
    let result1 = await this.getPromise1();

    let result2 = await this.getPromise2(result1.someData);

    //etc...

    this.commit();
}

这很好用,但是我遇到了麻烦。页面序列可以在任何阶段通过用户输入取消,因此构造将需要在该点中止。问题是,在每个阶段检查取消都变得令人厌倦和不优雅,而且对我来说感觉非常强烈,就像走错路一样。

async process() {
    let result1 = await this.getPromise1();
    if (result1.cancelled) {
        this.revert();
        return;
    }


    let result2 = await this.getPromise2(result1.someData);
    if (result2.cancelled) {
        this.revert();
        return;
    }

    //etc...

    this.commit();
}

我在哪里错了?我是否使用完全不正确的模式进行此类设置?有没有更优雅的方法来接近这种方法?或者,真的没有比这更好的方法吗?

2 个答案:

答案 0 :(得分:0)

一种可能的解决方案可能是让您的“网页”拒绝他们的承诺(即throw错误),以便catch process出现错误class App { async process() { try { let result1 = await this.getPromise1(); let result2 = await this.getPromise2(result1.someData); //etc... this.commit(); } catch (e) { this.revert(); } } async getPromise1() { return {someData: 'foo'}; } async getPromise2({someData}) { throw new Error('cancelled'); } } 功能。

a

答案 1 :(得分:0)

由于这是一个序列而你总是在你的承诺上测试cancelled,你可以创建一个你承诺扩展的接口

interface Prom {
    cancelled?: boolean
}

然后运行序列

const seq: Prom[] = [this.getPromise1(), this.getPromise2(),...]

for (let p of seq) {
    const res = await p
    if (res.cancelled) {
        return this.revert()
    }
}

或者,如果您承诺reject而不是将结果设置为cancelled(我会这样做),您可以从Promise.all的快速失败行为中受益:

try {
    await Promise.all([this.getPromise1(), this.getPromise2(),...])
catch(e) {
    //a promise was rejected
}

使用await时无法真正避免处理异常。 因此,如果您不想处理异常,请使用then

Promise.all([this.getPromise1(), this.getPromise2(),...]).then(
    () => { //success },
    (reason) => { // failure }
)