我正在尝试重构一些'同步'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?
答案 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);
}
}