функция javascript jquery это как-то неправильно?

#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:

С этим связано несколько проблем.

  1. Вызов getJSON является асинхронным, поэтому вам нужно быть осторожным, чтобы не пытаться использовать результаты до того, как вызов вернет ваши результаты.

  2. В том виде, в каком оно есть на данный момент, результаты не будут возвращены serviceJSONObject . return output Оператор задает возврат для анонимной функции, а не возвращаемое значение для rebuildJSONObject , поэтому результаты просто исчезнут. Если вы хотите, чтобы результаты были доступны в другом месте в коде, вам нужно будет либо сохранить их в глобальной переменной, либо получить к ним доступ внутри обратного вызова.