HTTP-клиент Titanium возвращает слишком «быстро» - PullRequest
3 голосов
/ 30 января 2012

У меня есть следующая функция:

  getTasks: function()
    {
        var taskRequest = Titanium.Network.createHTTPClient();
        var api_url = 'http://myawesomeapi.heroku.com/users/' + Ti.App.Properties.getString("userID") + '/tasks';

        var tasks = [];
        taskRequest.onload = function() {
            var response = JSON.parse(this.responseText), 
            len = response.length,
            i = 0,
            t;

            for(; i < len; i++)
            {
                task = response[i];
                var newTask = {};
                newTask.rowID = i;
                newTask.title = task.title;
                newTask.description = task.description;
                newTask.id = task.id;
                newTask.hasChild = true;

                tasks.push(newTask);
            }

            alert(tasks);
        }

        taskRequest.open('GET', api_url, false);
        taskRequest.setRequestHeader('Content-Type', 'application/json');
        taskRequest.send();

        alert(tasks);
            // return tasks;
    }

Эта функция в моем контроллере; Я называю это, на мой взгляд, когда мне нужно загрузить данные. Однако я хочу return эти данные, чтобы я мог назначить их переменной в представлении.

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

Теперь мой очевидный вопрос, как я могу заставить мою функцию возвращать массив с данными, а не без?

Установка таймера кажется едва ли правильным решением. Спасибо!

Ответы [ 2 ]

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

"Однако я хочу вернуть эти данные, чтобы я мог назначить их переменной в представлении."

Помимо выполнения запроса AJAX синхронный (который вам, вероятно, не нужен), вернуть данные невозможно.

Какой бы код ни опирался на ответ, его необходимо вызывать из обработчика ответа.

Поскольку функции можно передавать, вы можете иметь свой getTasks метод получать функцию обратного вызова, которая вызывается и получает массив tasks.

  getTasks: function( callback ) // receive a callback function
    {
        var taskRequest = Titanium.Network.createHTTPClient();
        var api_url = 'http://myawesomeapi.heroku.com/users/' + Ti.App.Properties.getString("userID") + '/tasks';

        taskRequest.onload = function() {

            var tasks = [];

            // code populating the tasks array

            alert(tasks);

            callback( tasks ); // invoke the callback
        }

        taskRequest.open('GET', api_url, false);
        taskRequest.setRequestHeader('Content-Type', 'application/json');
        taskRequest.send();
    }

Так что вы бы использовали это так ...

myObj.getTasks(function(tasks) {
    alert('in the callback');
    alert(tasks);
      // Any and all code that relies on the response must be
      //   placed (or invoked from) inside here
    some_other_function();
});

function some_other_function() {

    // Some more logic that can't run until the tasks have been received.
    // You could pass the tasks to this function if needed.

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

Вы получаете пустое alert, потому что при выполнении нижнего оповещения ответ сервера недоступен, а массив tasks пуст.

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

...