问题描述
我有以下功能:
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此数据,以便我可以将其分配给视图中的变量.
现在发生的事情是它返回空虚.最后一个警报(底部)似乎运行得太快了,它返回一个空数组,而仅在完成Onload功能后才被警报的数组包含我需要的内容.
现在我明显的问题,如何获得我的函数以使用数据返回数组,而不是没有?
在上面放一个计时器似乎是几乎不是正确的决定.谢谢!
推荐答案
"但是,我希望返回此数据,以便我可以将其分配给视图中的变量."
除了制作Ajax请求同步(您可能不需要),没有任何方法返回数据.
任何依赖响应的代码都需要从响应处理程序中调用.
由于可以通过函数传递,因此您可以将您的getTasks方法接收一个被调用的回调函数,并将接收tasks array.
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. }
其他推荐答案
您要空了alert,因为执行底部警报时,服务器响应不可用,并且tasks数组为空.
当服务器响应到达时,任务数组由您在onload处理程序中的代码填充,因此您在第二个警报中看到任务.
问题描述
I have the following function:
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; }
This function is in my controller; I call it in my view when I need to load the data in. However, I wish to return this data so I can assign it to a variable in the view.
Now what happens is that it returns emptiness. The last alert (bottom one) seems to be running too fast and it returns an empty array, while the one that only gets alerted after the onload function is done, contains what I need.
Now my obvious question, how can I get my function to return the array with the data, instead of without?
Putting a timer on it seems hardly the right decision.. Thanks!
推荐答案
"However, I wish to return this data so I can assign it to a variable in the view."
Aside from making the AJAX request synchronous (which you probably don't want), there isn't any way to return the data.
Whatever code relies on the response needs to be called from within the response handler.
Since functions can be passed around, you could have your getTasks method receive a callback function that is invoked and will receive the tasks Array.
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(); }
So you'd use it like this...
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. }
其他推荐答案
You are getting empty alert because when the bottom alert is executed the server response is not available and tasks array is empty.
When the server response comes the tasks array is populated by the code which you have in the onload handler so you see the tasks in the second alert.