我正在开发一个jQuery插件,它假装根据用户的浏览器语言自动翻译页面上的元素。翻译将存储在.json文件中。
当你调用插件时,你传递一个包名(或它们的数组),然后它将尝试以下列方式加载语言文件:
'en'
并且您只指明了一个包,它会尝试加载以下内容:packageName-en.json
packageName-en.json
AND packageName-en-US.json
所以,在插件中我有这个:
$.fn.Translator = function(pkg, options){
Translator.initialize(pkg, options).done(function(){
return this.each(Translator.translate);
});
};
所以,在我的初始化函数中,我有这个:
loadLanguages : function(){
$.each(self.options.packages,function(i, pkg){
});
}
将调用此函数:
getLanguage : function(pkg, language){
var self = this, url;
if (self.options.path)
url = self.options.path + '/';
url += [pkg, language].join('-');
return $.ajax ({
url : url,
dataType : "json",
cache : self.options.cache
});
}
问题在于,由于该函数可能会被多次调用,我不知道如何让initialize
返回一个将在调用所有函数后解析的promise。
答案 0 :(得分:2)
我知道你已经接受了答案,但有一种更简单的方法:使用$.when。
function loadLanguages () {
return $.when.apply( $, $.map( self.options.packages, function( pkg ) {
return getLanguage(pkg, language);
}) );
}
答案 1 :(得分:0)
要解决此问题,您可以创建一个虚拟Deferrer(baseDfr)并返回虚拟结果initialize()
。这里的想法是在完成所有baseDfr.resolve()
次呼叫时致电getLanguage()
。我们会跟踪使用计数器完成的getLanguage()
次呼叫的数量。当计数器达到0时,我们调用baseDfr.resolve()
。
我们知道getLanguage()
使用then()
或done()
方法在$.ajax
返回的延期者上完成调用。
可以在下面找到解决此问题的代码。此外,可以在此处找到一个工作示例(在某些div上):http://jsfiddle.net/c5NBr/。打开控制台以查看消息的正确顺序。
var packages = [];
var count = 0;
var baseDfr = $.Deferred();
var language = "en";
function resolveFunction () {
// By using this approach it is possible to pass a
// parameter to this resolve function.
return function(){
if ( !(--count) ) {
// Until count is 0, we won't resolve the base
// deferrer object.
// As long as this isn't called, the function
// done() of initialize won't be called either.
baseDfr.resolve();
}
};
}
function getLanguage (pkg, language){
var self = this, url;
if (self.options.path)
url = self.options.path + '/';
url += [pkg, language].join('-');
return $.ajax ({
url : url,
dataType : "json",
cache : self.options.cache
}).promise();
}
function loadLanguages () {
$.each(self.options.packages,function(i, pkg){
getLanguage(pkg, language).then(resolveFunction());
});
return baseDfr.promise();
}
function initialize(options) {
packages = options.packages;
count = options.packages.length;
return loadLanguages();
}
var options = {
packages : $('div')
};
initialize(options).done(function(){
// This will only be called when baseDfr.resolve() is called.
console.log("Fired all getLanguage().");
});