jQuery: как вернуть, когда данные условно запрашиваются через AJAX? - PullRequest
1 голос
/ 23 января 2012

У меня есть функция, вызывающая другую функцию для получения данных. Эти данные могут быть локально кэшированы, или мне, возможно, придется получить их. Локально кешируется легко. Но если я получу его через $ .getJSON, не блокируя браузер, отключив асинхронный режим, есть ли способ вернуть эти данные в исходную функцию?

Т.е. в следующем коде:

1) Поскольку bar () больше не существует при возврате parseData (), куда отправляется dataX?

2) Не имея еще одного уровня обратного вызова, который вызывали бы и bar (), и parseData (), и не блокируя браузер во время выполнения запроса, как я могу вернуть dataX из parseData () в foo ()?

var foo = function () {

    $('body').text(bar());

};

var bar = function () {

    var parseData = function (dataX) {
        // do something to data
        return dataX;
    };

    if (localStorage.hasOwnProperty('someKey')) {
        return localStorage.getItem('someKey');
    else {
        $.getJSON('http://somewhere.api.com?fubar=good', parseData);
    }

};

Ответы [ 3 ]

2 голосов
/ 23 января 2012

Невозможно вернуться при выполнении асинхронных вызовов.Вместо этого просто вызовите foo в качестве обратного вызова:

var foo = function (text) {

    $('body').text(text);

};

var bar = function () {

    var parseData = function (dataX) {
        // do something to data
        foo(dataX.someText);
    };

    if (localStorage.hasOwnProperty('someKey')) {
        foo(localStorage.getItem('someKey'));
    else {
        $.getJSON('http://somewhere.api.com?fubar=good', parseData);
    }

};
2 голосов
/ 23 января 2012

Нет возврата из функции bar, поэтому вызов ее напрямую в функции text() jQuery не приведет к установке текста (поскольку возвращение не является текстом).

Вы можетеизмените поток кода, чтобы передать элемент, текст которого вы хотите изменить, и заставить функцию parseData вызвать функцию .text() для элемента:

var foo = function () {

    //here we call the `bar` function and pass the element we want to change the text of as an argument
    bar('body');

};

var bar = function (element_str) {

    //here we use the argument we passed to create a jQuery object of the element to use later
    var $element = $(element_str);

    var parseData = function (dataX) {

        //instead of trying to return the value from the server, we just set the text of the element passed in
        $element.text(dataX);
    };

    if (localStorage.hasOwnProperty('someKey')) {

        //here we manually call the `parseData` function to add the locally stored string to the DOM
        parseData(localStorage.getItem('someKey'));
    else {

        //here we pass the `parseData` function as the callback function for this AJAX call so it can set the text in the DOM when the AJAX function has come back successfully
        $.getJSON('http://somewhere.api.com?fubar=good', parseData);
    }

};
0 голосов
/ 23 января 2012

Это невозможно из-за асинхронного запроса, если только запрашиваемый сервер не поддерживает CORS, и в этом случае вы можете сделать запрос синхронным. Я бы не советовал делать это из-за плохой работы браузера, которая может вызвать.

Я предлагаю разрешить bar принимать обратный вызов, который можно использовать для выполнения действия по завершению.

Редактировать:

Попробуйте это:

var foo = function () {

    $('body').text(bar());

};

var bar = function () {

    var parseData = function (dataX) {
        // do something to data
        localStorage.setItem('someKey',dataX);
        foo();
    };

    if (localStorage.hasOwnProperty('someKey')) {
        return localStorage.getItem('someKey');
    else {
        $.getJSON('http://somewhere.api.com?fubar=good', parseData);
        return "loading...";
    }

};

Что происходит, когда браузер не поддерживает localStorage? или вы просто не ориентируетесь на эти браузеры.

...