Есть ли версия $getJSON, которая не использует обратный вызов?
Я реализую функцию обратного вызова для библиотеки javascript 3rdParty, и мне нужно вернуть значение, но мне нужно получить значение с сервера. Мне нужно сделать что-то вроде этого:
3rdPartyObject.getCustomValue = function {
return $.getJSON('myUrl');
}
getJson использует XMLHttpRequest, который (я считаю) имеет синхронное и асинхронное поведение. Могу ли я использовать синхронное поведение?
6 ответов
Глядя на исходный код jQuery, это все $.getJSON
делает:
getJSON: function( url, data, callback ) {
return jQuery.get(url, data, callback, "json");
},
И это все $.get
делает:
get: function( url, data, callback, type ) {
// shift arguments if data argument was omitted
if ( jQuery.isFunction( data ) ) {
callback = data;
data = null;
}
return jQuery.ajax({
type: "GET",
url: url,
data: data,
success: callback,
dataType: type
});
},
Там нет черной магии. Так как вам нужно настроить вещи, кроме основного $.getJSON
функциональность, вы можете просто использовать низкоуровневый $.ajax
и передайте асинхронную опцию как false:
$.ajax({
type: 'GET',
url: 'whatever',
dataType: 'json',
success: function() { },
data: {},
async: false
});
Вы также можете использовать следующее перед тем, как позвонить:
$.ajaxSetup( { "async": false } );
Я не знаю область действия свойства "async", я подозреваю, что это глобальная конфигурация. Так что подумайте, хотите ли вы изменить это обратно на true после синхронного вызова.
пример:
3rdPartyObject.getCustomValue = function {
$.ajaxSetup( { "async": false } );
var result = $.getJSON('myUrl');
$.ajaxSetup( { "async": true } );
return result;
}
var jsonObjectInstance = $.parseJSON(
$.ajax(
{
url: "json_data_plz.cgi",
async: false,
dataType: 'json'
}
).responseText
);
Но если я не ошибаюсь, этот код не будет работать:
3rdPartyObject.getCustomValue = function {
var json = $.ajax({
type: 'GET',
url: 'whatever',
dataType: 'json',
success: function() { },
data: {},
async: false
});
return json;
}
Поскольку $.ajax возвращает объект XHR, а не анализируемый объект json.
Вам нужно будет сделать что-то вроде:
var jsonLoader = function(url){
this.url = url;
this.rawData = {};
this.getRawData();
};
jsonLoader.prototype.getRawData = function(){
var json = $.ajax({
type: 'GET',
url: this.url,
dataType: 'json',
success: this.getRawData(this),
data: {},
async: false
});
};
jsonLoader.prototype. getRawData = function(self){
return function(json){self.rawData = json;};
};
var loadMe = new jsonLoader("Data.json");
loadMe.rawData //has the parsed json object
На самом деле, вероятно, есть гораздо более аккуратный способ достижения того же
Если кто-то когда-либо должен делать это в рельсах, у меня есть довольно чистый способ, как это:
Настройте свой контроллер следующим образом:
def my_ajax_action respond_to do |format| # if you use render, you won't need a view page, the ":json =>" part takes care of all # the formatting format.json { render :json => @variable_containing_json } end end
Настройте звонок в Javascript
function doAjaxWork( ) { var ret; $.ajax({ type: 'GET', url: '/controller/action/param', dataType: 'json', complete: function(response) { ret = eval('(' + response.responseText + ')'); }, async: false }); return ret; }
Конечно, не делайте эту синхронизацию без необходимости. Да, и пока я показываю javascript с URL-адресами, проверьте JSRoutes... это делает их действительно чистыми.
Область действия свойства async является глобальной, ваш метод синхронизирует вызов.