jQuery 延迟 AJAX 调用 return 值
jQuery deferred AJAX call return value
我有一个函数,它将 return 一个缓存的模板,或者如果模板没有被缓存 - 它会通过 AJAX 加载它,然后 return 它。这是我得到的:
var getTpl = function( name ) {
var cached = cache.get( 'templates' ) || {};
if( cached.hasOwnProperty( name ) ) {
console.log( 'template ' + name + '.mustache found in cache' );
return cached[ name ];
}
else {
console.log( 'requesting ' + name + '.mustache template via AJAX' );
var tpl;
$.ajax( {
url: path.templates + '/' + name + '.mustache',
async: false,
success: function( data ) {
tpl = data;
var cached = store.get( 'miniTemplates' ) || {};
var newTemplate = {};
newTemplate[ name ] = data;
if( ! cached.hasOwnProperty( name ) ) cache.set( 'templates', _.extend( cached, newTemplate ) )
},
error: function() { tpl = false; }
} );
return tpl;
}
}
这很好用。但是,Chrome 抱怨:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
因此我想改用 $.deferred
,但我无法理解它。我怎样才能重写上面的函数,所以调用 getTpl
总是 return 一个模板(形成缓存或直接来自 AJAX 请求)?
您可以使用promise/deferred概念来实现您的需求
var getTpl = function( name ) {
var promise;
var cached = cache.get( 'templates' ) || {};
if( cached.hasOwnProperty( name ) ) {
console.log( 'template ' + name + '.mustache found in cache' );
var df = new $.Deferred();
df.resolve(cached[ name ]);
promise = df.promise();
} else {
console.log( 'requesting ' + name + '.mustache template via AJAX' );
promise = $.ajax({
url: path.templates + '/' + name + '.mustache'
}).then(function(data) {
tpl = data;
var cached = store.get( 'miniTemplates' ) || {};
var newTemplate = {};
newTemplate[ name ] = data;
if( ! cached.hasOwnProperty( name ) ) cache.set( 'templates', _.extend( cached, newTemplate ) )
return tpl;
});
}
return promise;
}
然后,像这样调用你的方法:
getTpl('xyz')
.then(function(template) {
// you have the template, either from cache or fetched via ajax
})
.fail(function(err) {
console.log(err);
});
由于您似乎已经在使用 underscore/lodash,您可以使用记忆而不是维护自己的缓存。
promise 的美妙之处在于您可以一次又一次地访问它们,并且它们将始终产生相同的值:
var getTpl = _.memoize(function( name ) {
console.log( 'requesting ' + name + '.mustache template via AJAX' );
return $.ajax({
url: path.templates + '/' + name + '.mustache'
});
});
是的,就是这么简单。
然后你就可以像使用任何其他 promise 一样使用它了:
getTpl('myTemplate').then(function (template) {
// use template
}, function (error) {
console.log('Could not retrieve template.', error);
});
我有一个函数,它将 return 一个缓存的模板,或者如果模板没有被缓存 - 它会通过 AJAX 加载它,然后 return 它。这是我得到的:
var getTpl = function( name ) {
var cached = cache.get( 'templates' ) || {};
if( cached.hasOwnProperty( name ) ) {
console.log( 'template ' + name + '.mustache found in cache' );
return cached[ name ];
}
else {
console.log( 'requesting ' + name + '.mustache template via AJAX' );
var tpl;
$.ajax( {
url: path.templates + '/' + name + '.mustache',
async: false,
success: function( data ) {
tpl = data;
var cached = store.get( 'miniTemplates' ) || {};
var newTemplate = {};
newTemplate[ name ] = data;
if( ! cached.hasOwnProperty( name ) ) cache.set( 'templates', _.extend( cached, newTemplate ) )
},
error: function() { tpl = false; }
} );
return tpl;
}
}
这很好用。但是,Chrome 抱怨:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
因此我想改用 $.deferred
,但我无法理解它。我怎样才能重写上面的函数,所以调用 getTpl
总是 return 一个模板(形成缓存或直接来自 AJAX 请求)?
您可以使用promise/deferred概念来实现您的需求
var getTpl = function( name ) {
var promise;
var cached = cache.get( 'templates' ) || {};
if( cached.hasOwnProperty( name ) ) {
console.log( 'template ' + name + '.mustache found in cache' );
var df = new $.Deferred();
df.resolve(cached[ name ]);
promise = df.promise();
} else {
console.log( 'requesting ' + name + '.mustache template via AJAX' );
promise = $.ajax({
url: path.templates + '/' + name + '.mustache'
}).then(function(data) {
tpl = data;
var cached = store.get( 'miniTemplates' ) || {};
var newTemplate = {};
newTemplate[ name ] = data;
if( ! cached.hasOwnProperty( name ) ) cache.set( 'templates', _.extend( cached, newTemplate ) )
return tpl;
});
}
return promise;
}
然后,像这样调用你的方法:
getTpl('xyz')
.then(function(template) {
// you have the template, either from cache or fetched via ajax
})
.fail(function(err) {
console.log(err);
});
由于您似乎已经在使用 underscore/lodash,您可以使用记忆而不是维护自己的缓存。
promise 的美妙之处在于您可以一次又一次地访问它们,并且它们将始终产生相同的值:
var getTpl = _.memoize(function( name ) {
console.log( 'requesting ' + name + '.mustache template via AJAX' );
return $.ajax({
url: path.templates + '/' + name + '.mustache'
});
});
是的,就是这么简单。
然后你就可以像使用任何其他 promise 一样使用它了:
getTpl('myTemplate').then(function (template) {
// use template
}, function (error) {
console.log('Could not retrieve template.', error);
});