Доступ к внешней области в JavaScript - PullRequest
5 голосов
/ 13 июля 2011

Итак, у меня есть этот JS-код, и я пытаюсь установить obj из коллбэков success и error, но, видимо, область действия toLinkInfo не является родительской областью для этих?Я всегда получаю нулевое значение от этой функции, несмотря ни на что.Я перепробовал кучу вещей, но не смог заставить их работать, я думаю, я слишком привык к C и друзьям :) Как я могу заставить это работать?

LinkInfoGrabber.prototype.toLinkInfo = function() {
    var obj = null;
    $.ajax({
        url: this.getRequestUrl(),
        success: function(raw) {
            obj = new LinkInfo(raw);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            obj = new LinkInfoException(jqXHR, textStatus, errorThrown);
        },
        dataType: 'html'
    });

    if (obj instanceof LinkInfo) {
        return obj;
    } else {
        throw obj;
    }
}

Ответы [ 3 ]

3 голосов
/ 13 июля 2011

Этот код:

if (obj instanceof LinkInfo) {
        return obj;
    } else {
        throw obj;
    }

запускается сразу после запуска вызова ajax, но obj не устанавливается до успешного завершения вызова ajax. Это распространенное недоразумение. Вызов Ajax является асинхронным. Ваш вызов $ .ajax () запускает асинхронный вызов, а затем немедленно выполняется остальная часть вашей функции. Обработчик успеха вызывается только в случае успешного вызова ajax (через некоторое время). Вы не можете вернуть obj из своей функции. Вы должны обработать obj в вашем обработчике успеха, а затем вызвать все, что захочет использовать его из обработчика успеха.

3 голосов
/ 13 июля 2011

Это потому, что вызовы AJAX асинхронны - они происходят в другое время, чем остальная часть контекста.

Попробуйте дать ему функцию обратного вызова (называемую обратным вызовом ниже).

LinkInfoGrabber.prototype.toLinkInfo = function(callback) {
    $.ajax({
        url: this.getRequestUrl(),
        success: function(raw) {
            callback( new LinkInfo(raw) );
        },
        error: function(jqXHR, textStatus, errorThrown) {
            obj = new LinkInfoException(jqXHR, textStatus, errorThrown);
        },
        dataType: 'html'
    });
}

var l = new LinkInfoGrabber()
l.toLinkInfo(console.log) //replace console.log with something meaningful

Хотя этот подход не дает точно такой же результат, как возможность вызова всего встроенного, он имеет то преимущество, что допускает асинхронную природу сети.

0 голосов
/ 13 июля 2011

Вы возвращаете obj перед возвратом вызова ajax, поэтому при возврате он не устанавливается ничего, кроме нуля.

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