【问题标题】:How to create a tree of promises?如何创建一棵承诺树?
【发布时间】:2014-07-24 19:13:50
【问题描述】:

我正在尝试在 Ember 中创建一棵承诺树。

        return this.store.find('session', 'session').then(function(session) {
            if (session.get('isEmpty')) {
                return this.store.createRecord('session').save().then(function(session) {
                    session.set('id', 'session');

                    return session.save();
                }.bind(this));
            } else {
                return session;
            }
        }.bind(this), function(session) {
            return this.store.createRecord('session').save().then(function(session) {
                session.set('id', 'session');

                return session.save();
            }.bind(this));
        }.bind(this)).then(function(session) {
            this.controllerFor('application').onLanguageChange();

            this.set('localStorage.session', session);

            return session;
        }.bind(this));

我想执行如下所示的承诺。提到还有嵌套的 promise createRecord(..).save().then。有可能这样做吗?

这里不完全是一棵承诺树,因为最后一个应该为两个分支执行。如果我把它们放在一个自己的函数中,当然可以。像这样:

'successBranch'.then(function(session) {
   setSessionDependents(session);
   return session;
}

'failBranch'.then(function(session) {
   setSessionDependents(session);
   return session;
}

function setSessionDependents(session) {
    this.controllerFor('application').onLanguageChange();

    this.set('localStorage.session', session);
}

【问题讨论】:

  • 是的,当然可以。不行吗?
  • 我的生命是一棵承诺树...

标签: javascript ember.js promise


【解决方案1】:

两个分支都应该执行最后一个

确实如此!如果错误处理程序没有throw 异常,则错误已被处理,并且承诺确实使用处理程序的return 值解决。

有可能吗?

是的!这是 then 的核心属性之一,它通过嵌套的 Promise 解决。

但是,您可以稍微简化代码,因为那里有很多重复项:

return this.store.find('session', 'session').then(function(session) {
    if (session.get('isEmpty')) {
        throw new Error("no session found");
    else
        return session;
}).then(null, function(err) {
    return this.store.createRecord('session').save().then(function(session) {
        session.set('id', 'session');
        return session.save();
    });
}.bind(this)).then(function(session) {
    this.controllerFor('application').onLanguageChange();
    this.set('localStorage.session', session);
    return session;
}.bind(this));

【讨论】:

  • 我读到,在使用 Promise 时,您应该将它们放在彼此后面而不是在里面。有没有办法像这样重构这段代码?
  • 我猜是链接而不是嵌套?
  • 或者在这种情况下嵌套不是一个坏习惯?感谢您提供的答案!我想我在测试过程中忽略了一些东西。非常感谢重构的答案:)
  • 不,如果有不同的控制流路径,一定程度的嵌套总是必要的。除此之外,promise 提供了能力 来展平金字塔,这不是绝对必要的。在我的代码中,您可以看到 3 个链接的 .then() 调用,并且只有一个嵌套。
  • 我认为同步示例在这里真的很有帮助:)
猜你喜欢
  • 1970-01-01
  • 2017-09-21
  • 1970-01-01
  • 2011-10-27
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 2020-12-05
  • 2016-05-19
相关资源
最近更新 更多