Кажется, JavaScript останавливается после вызова AJAX - PullRequest
2 голосов
/ 02 декабря 2011

Название вопроса довольно расплывчато, но вот моя ситуация. У меня есть примерно 700+ строк jQuery для веб-приложения, каждая функция и «основная точка интереса» в коде, отмеченном журналом для консоли при его запуске. Например, у меня есть несколько функций, которые используют AJAX-вызов сервлета для получения некоторой информации. Я регистрируюсь, когда начинается запрос AJAX, если он выполнен успешно (затем распечатываю, какие данные он собрал) и т. Д. Итак, судя по тому, что записала моя консоль, когда я открываю страницу, она кажется остановленной после первого вызова AJAX. Конечно, вызов, казалось, работал просто отлично, и данные, которые он возвратил, были прекрасны. Как вы увидите, он даже заполнил поле выбора как задумано. Однако вскоре после этого журналы консоли останавливаются, что заставляет меня поверить, что по какой-то причине другие функции не вызываются ...

JQuery

$(document).ready(function() {
    Initialize();
});
function Initialize() {
    console.log("Initializing...");
    User();
    Widgets();
    if($.cookie("fogbugzId") != null) {
        console.log("Stored ID: " + $.cookie("fogbugzId"));
        $("#userSelect").val($.cookie("fogbugzId")).trigger("change");
        $("#userSelect").hide();
    } else console.log("No ID Stored!");
}
function User() {
    console.log("Initializing User...");
    $.each(FetchUsers(), function(index, user) {
        $("#userSelect").append($("<option>").val(user.id).text(user.name));
    });
    $("#userSelect").change(function() {
        if($("#userSelect").val() != "") {
            console.log("User Changed to " + $("#userSelect").val() + ": " + $("#userSelect").text());
            $.cookie("fogbugzId", $("#userSelect").val(), { expires: 365 });
        }
        Update();
    });
    console.log("User Initialized!");
}
function FetchUsers() {
    console.log("Loading Users...");
    $("#loading").show();
    $.get(servlet, { command: "getUsers" }, function(data) {
        var users = new Array();
        $(data).find("user").each(function() {
            users.push({
                id: $(this).find("id").text(),
                name: $(this).find("name").text()
            });
        });
        $.each(users, function(index, user) {
            console.log(">> " + user.id + ": " + user.name);
        });
        console.log("Users Loaded!");
        return(users);
    }, "xml").complete(function() {
        $("#loading").hide();
    }).error(function() {
        console.log("Loading Users Failed!");
    });
}
function Widgets() {
    console.log("Initializing Widgets...");
    // More Code
    console.log("Widgets Initialized!");
}

Консоль

Initializing...
Initializing User...
Loading Users...
>> 267: Alex Molthan
>> 35: Bill Brinkoetter
>> 100: Bob Yoder
>> 189: Brian Cutler
>> 559: Brian Ormond
>> 400: Corey Nakamura
Users Loaded!

Но запись останавливается тут же. Таким образом, вызов AJAX для извлечения пользователей из базы данных работает нормально, но, очевидно, функция User() не может завершиться должным образом. Единственная ошибка, которую дает мне консоль JavaScript, - это ошибка в моем файле jquery.min.js:

Uncaught TypeError: Cannot read property 'length' of undefined  jquery.min.js:16
    f.e.extend.each                                             jquery.min.js:16
    User                                                        modifytime.js:14
    Initialize                                                  modifytime.js:3
    (anonymous function)                                        modifyTime.jsp:21
    f.extend._Deferred.e.resolveWith                            jquery.min.js:16
    f.e.extend.ready                                            jquery.min.js:16
    f.c.addEventListener.B                                      jquery.min.js:16

Похоже, что он ломается на $.each(), который перебирает массив пользователей, возвращаемых функцией FetchUsers(). Я знаю, что функция возвращает пригодный для использования массив, поэтому я не уверен, что он застревает. Кто-нибудь может увидеть то, что мне не хватает сразу? Я попытался присвоить users[], возвращаемому функцией FetchUsers(), сначала переменной, а затем передать ее в $.each(), но это все равно не сработало. Есть предложения?

Редактировать : после замены свернутой версии jQuery на несжатую версию кажется, что массив пользователей, которые я передаю в функцию $.each(), теперь имеет свойство .length, поэтому это ломается Просто чтобы проверить, прежде чем я вызову эту конкретную функцию $.each(), я поместил журнал users[].length, возвращенный функцией FetchUsers(), чтобы убедиться, что у нее все еще нет свойства .length. Затем я пошел к самой функции FetchUsers() и поместил журнал users[].length как раз перед тем, как вернуть его. Этот журнал, однако, работает отлично (хотя мой пример не показывает его, он возвращает 40 пользователей). Так что мой users[] не возвращается как массив или что-то еще?

Ответы [ 2 ]

0 голосов
/ 02 декабря 2011

FetchUsers ничего не возвращает, даже не имеет оператора возврата. Кроме того, $ .get является асинхронной функцией, поэтому вы не можете вернуть значение, которое она передает обратному вызову из функции FetchUsers. Вместо этого вы могли бы заставить FetchUsers принять обратный вызов, который он вызывает, когда получил данные пользователя (и в этом случае сделать это изменение было бы относительно тривиально):

function User() {
    console.log("Initializing User...");
    FetchUsers(function(user) { // Changed!
        $("#userSelect").append($("<option>").val(user.id).text(user.name));
    });
    <...>
}

function FetchUsers(callback) { // Changed!
    console.log("Loading Users...");
    $("#loading").show();
    $.get(servlet, { command: "getUsers" }, function(data) {
        //var users = new Array(); No longer necessary.
        $(data).find("user").each(function() {
            callback({ // Changed!
                id: $(this).find("id").text(),
                name: $(this).find("name").text()
            });
        });
        <...>
}

Изменение этих трех строк с помощью "Изменено!" комментария должно быть достаточно, чтобы он работал правильно. (Хотя ваша регистрация полученных пользователей должна быть слегка изменена, поскольку они больше не помещаются в массив.)

0 голосов
/ 02 декабря 2011

Признаюсь, я не читал и не понимал каждую часть вашего источника (и не проверял, закрыты ли все скобки), но FetchUsers явно НЕ возвращает ничего (вопреки вашему утверждению) - так что вызов FetchUsers () оценивается как «неопределенный». Исправление потребует некоторого переписывания, так как в Javascript вы не можете реально вернуть результат асинхронной операции (например, $ .get) из синхронной функции (например, FetchUsers ()) - это потребует многопоточности (какая-то блокировка, ожидание и т. Д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...