#javascript #jquery #function
#javascript #jquery #функция
Вопрос:
function rebuildJSONObject(){
$.getJSON('services.json', function(data) {
//stof start
var input = data;
var output = { myservices: [] };
for (var key in input) {
if (input.hasOwnProperty(key)) {
for (var i = 0, hostsinfo = input[key].hostsinfo; i < hostsinfo.length; i ) {
output.myservices.push({
'nametag': key,
'hostidn': hostsinfo[i]['hostidn'],
'details': hostsinfo[i]['details'],
'currstatus': hostsinfo[i]['currstatus'],
'currstatusclass': hostsinfo[i]['currstatusclass']
});
}
}
}
//stof end
return output;
});
}
//setting it for use later in the script
var serviceJSONObject = rebuildJSONObject();
Я знаю, что все, что происходит в функции, работает правильно, потому что, если я применяю ее к событию щелчка, она работает очаровательно. Однако я бы предпочел загрузить объект JSON в память один раз и работать с ним на стороне клиента после того, как он не будет сохранен. Однако моя проблема в том, что везде, где я вызываю «serviceJSONObject», я получаю ошибку «undefined».
Итак, как я делаю это неправильно и как мне определить такую переменную в начале игры, чтобы остальная часть скрипта могла использовать указанную переменную.
Ответ №1:
Проблема в том, что output
возвращается до вызова функции обратного вызова. Вы должны иметь возможность сохранить значение с serviceJSONObject
помощью замыкания:
function rebuildJSONObject(serviceJSONObject){
$.getJSON('services.json', function(data) {
//stof start
var input = data;
// Use the serviceJSONObject that is passed into rebuildJSONObject
serviceJSONObject = { myservices: [] };
for (var key in input) {
if (input.hasOwnProperty(key)) {
for (var i = 0, hostsinfo = input[key].hostsinfo; i < hostsinfo.length; i ) {
serviceJSONObject.myservices.push({
'nametag': key,
'hostidn': hostsinfo[i]['hostidn'],
'details': hostsinfo[i]['details'],
'currstatus': hostsinfo[i]['currstatus'],
'currstatusclass': hostsinfo[i]['currstatusclass']
});
}
}
}
//stof end
});
}
//setting it for use later in the script
var serviceJSONObject;
rebuildJSONObject(serviceJSONObject);
Комментарии:
1. Я полагаю, что проблема по-прежнему будет заключаться в том, что нет ничего, что могло бы предотвратить доступ к serviceJSONObject до возврата вызова JSON. Он по-прежнему будет неопределенным, если доступ к нему будет получен до возврата вызова ajax.
2. @njreed.myopenid.com верно, последующий код
rebuildJSONObject(serviceJSONObject);
может нуждаться вserviceJSONObject
переменной раньше, чемrebuildJSONObject
будет возвращен.
Ответ №2:
Почему бы не добавить свойство кэша к функции, которая будет хранить результат начального вывода (загруженный через ajax) и возвращать сохраненное состояние при любом последовательном вызове.
function rebuildJSONObject(callback) {
var self = this;
if (typeof self.cache !== 'undefined') {
if (typeof callback === 'function') {
callback(self.cache);
}
return;
}
$.getJSON('services.json', function(data) {
//stof start
var input = data,
output = { myservices: [] };
for (var key in input) {
if (input.hasOwnProperty(key)) {
for (var i = 0, hostsinfo = input[key].hostsinfo; i < hostsinfo.length; i ) {
output.myservices.push({
'nametag': key,
'hostidn': hostsinfo[i]['hostidn'],
'details': hostsinfo[i]['details'],
'currstatus': hostsinfo[i]['currstatus'],
'currstatusclass': hostsinfo[i]['currstatusclass']
});
}
}
}
//stof end
self.cache = output;
if (typeof callback === 'function') {
callback(self.cache);
}
return;
});
}
РЕДАКТИРОВАТЬ: в первый раз вам нужно будет вызвать эту функцию асинхронно и предоставить функцию обратного вызова, например
rebuildJSONObject(function(output) {
/*
* Process your output here
*/
console.log(output);
});
Каждый раз подряд вы можете снова использовать его синхронно:
console.log(rebuildJSONObject.cache);
Комментарии:
1. Вызов ajax не синхронизирован, поэтому rebuildJSONObject ничего не возвращает.
2. как бы я тогда получил доступ к двусмысленности serviceJSONObject ? Например, у меня есть событие нажатия кнопки, в котором я проверяю длину объекта / переменной, чтобы убедиться, что там что-то есть .. теперь, фактически не определяя его как переменную, я бы назвал это как rebuildJSONObject().length ?
3. @PoweRoy, если он не дает результата, или он не даст мне ни одного слова. Как я могу получить переменную через любую форму транзакции AJAX, которую я могу сохранить на стороне клиента? для работы. Это длится дольше, чем продолжительность функции?
4. Вот почему обычно лучше работать с переменной внутри обратного вызова. Однако, если вы хотите, чтобы она была доступна в другом месте, у вас нет другого выбора, кроме как поместить ее в переменную с более высокой областью действия (т. Е. Глобальную)
5. Сохраните его в переменной вне функции или передайте его по переменной функции (см. Ответ Smirkins)
Ответ №3:
С этим связано несколько проблем.
-
Вызов getJSON является асинхронным, поэтому вам нужно быть осторожным, чтобы не пытаться использовать результаты до того, как вызов вернет ваши результаты.
-
В том виде, в каком оно есть на данный момент, результаты не будут возвращены
serviceJSONObject
.return output
Оператор задает возврат для анонимной функции, а не возвращаемое значение дляrebuildJSONObject
, поэтому результаты просто исчезнут. Если вы хотите, чтобы результаты были доступны в другом месте в коде, вам нужно будет либо сохранить их в глобальной переменной, либо получить к ним доступ внутри обратного вызова.