根据承诺值分配骨干URL

时间:2015-10-07 17:15:37

标签: javascript backbone.js promise

我正在尝试重构一些'同步'ajax代码(使用async:false从json文件中获取一些配置属性并返回它们)。我删除了async:false,现在返回一个使用该值解析的promise。

某些返回值是需要用作主干模型和集合的URL属性的URL。所以函数(在Config.js中)以前是

getUrl: function () {
    $.ajax({
        url: 'config.json',
        async: false,
        dataType: 'json',
        success: function (response) {
           this.applicationUrl = response.applicationUrl;
        }
    });
    return this.applicationUrl;
}

然后在集合或模型的URL属性中,它具有:

url: function () {
    return Config.getUrl();
}

所以我尝试解决这个问题的方法是让getURL函数返回一个promise,就像这样:

getUrl: function () {
    var deferred = $.Deferred();

    if (this.applicationUrl) {
        deferred.resolve(this.applicationUrl);
    } else {
        $.ajax({
            url: 'config.json',
            dataType: 'json',
            success: function (response) {
               this.applicationUrl = response.applicationUrl;
               deferred.resolve(this.applicationUrl);
            }
        });
    }
    return deferred.promise();
}

然后在模型/集合的initialize方法中,我调用:

initialize: function () {
    Config.getUrl().done(function (url) {
        this.baseUrl = url;
    });
},
url: function () {
    return this.baseUrl;
}

但是有没有办法确保在url需要用于获取之前解决了promise?

1 个答案:

答案 0 :(得分:1)

您可以看到here Backbone无法处理url的承诺。

这里我将promise函数分配给模型上的属性,并检查同步方法上的状态以确保它首先被解析。

initialize: function () {
    this._getUrl = Config.getUrl();

    this._getUrl.done(function (url) {
       this.url = url;
    }.bind(this));
},

sync: function(method, model, options) {
    options || (options = {});

    if (this._getUrl.state() === 'pending') {
     return this._getUrl.done(function (url) {
       options.url = url;

       return sync();
     }.bind(this));
    } else {
      return sync();
    }

    function sync() {
      return Backbone.sync.call(model, method, options);
    }
}