Передать результат из функции загрузки в переменную

Это модуль в моем приложении для iPhone. Его цель — вернуть массив из JSON responeText, который затем можно добавить к свойству данных TableView в другом модуле.

Будучи относительно новым в JavaScript, я не могу найти правильный синтаксис для передачи моего массива в переменную self.

function Events() {
var self = [];

var xhr = Ti.Network.createHTTPClient();
xhr.open('GET', 'http://localhost/ngparser/events.php');

xhr.onload = function() {
    var events = JSON.parse(this.responseText),
        rows = [];

    Ti.API.info('JSON responseText: ');
    Ti.API.info(events);

    for (var i in events) {
        var id = events[i].id,
            title = events[i].title;            

        var amp = title.search('&');
        if (amp != -1) {
            title = title.replace('&', '&');
        }

        var row = Ti.UI.createTableViewRow({
            title: title,
            hasChild: true
        });
        rows.push(row);         
    }

    // I want this...
    return rows;        
};

xhr.send();
self = //... to end up here!
self = xhr.send(); //Does not work
return self;
}

module.exports = Events;

РЕДАКТИРОВАТЬ: в конечном итоге решение было найдено здесь http://developer.appcelerator.com/question/133913/how-do-i-pass-result-from-xhronload-function-to-variable#comment-119031


person Gabriel Smoljár    schedule 16.03.2012    source источник


Ответы (2)


Функция xhr.onload работает асинхронно и не возвращает значение, поэтому возвращать переменную rows бесполезно.

Что вы можете сделать, так это использовать метод setData табличного представления внутри функции обратного вызова, чтобы добавить массив строк в табличное представление.

function Events() {
var self = [];

var xhr = Ti.Network.createHTTPClient();
xhr.open('GET', 'http://localhost/ngparser/events.php');

xhr.onload = function() {
    var events = JSON.parse(this.responseText),
        rows = [];

    Ti.API.info('JSON responseText: ');
    Ti.API.info(events);

    for (var i in events) {
        var id = events[i].id,
            title = events[i].title;            

        var amp = title.search('&');
        if (amp != -1) {
            title = title.replace('&', '&');
        }

        var row = Ti.UI.createTableViewRow({
            title: title,
            hasChild: true
        });
        rows.push(row);         
    }
    tableView.setData(rows);

};

xhr.send();
}
person DannyM    schedule 16.03.2012
comment
Я играл с обратными вызовами, но не могу заставить его работать. Мои событияCallback, похоже, не запускаются, так как нет вывода из информации(). Модуль окна: pastebin.com/1kdga075 Модуль данных: pastebin.com/bQVi55Pn - person Gabriel Smoljár; 16.03.2012
comment
Если обратный вызов onload не срабатывает, то должна быть ошибка. Попробуйте добавить info() в обратный вызов onerror и посмотрите, срабатывает ли он. - person DannyM; 16.03.2012
comment
xhr.onload в Events() действительно срабатывает, так как я получаю вывод от info() в функции, я имел в виду eventsCallback() в EventsWindow. Извини за это. Я добавил xhr.onerror = function(e) {Ti.API.info(e.error);} в Events(), и в консоли нет ошибки. - person Gabriel Smoljár; 16.03.2012

AJAX является асинхронным, функция onload запускается, когда выполняется вызов AJAX. Это означает, что JavaScript продолжает выполнять вашу функцию и запускается onload позже. Это означает, что вы не можете вернуть значение из него.

Вам нужно поместить весь код, относящийся к переменной rows (или self), внутрь функции onload.

person Rocket Hazmat    schedule 16.03.2012