我正在编写一个钛应用程序,但我的javascript执行顺序存在问题。
我在按钮上有一个事件监听器。它是一个重新加载按钮,用于清除表,使用HTTPClient获取“约会”的JSON数组,保存每个约会,并刷新表列表。问题是我首先执行表删除应该清除表,然后我得到约会,但是当应用程序刷新数据表时,它就像它正在做太快而且新的约会还没有保存,因为我得到了一个空列表。现在,如果我注释掉db.deleteAll行,每次单击重新加载列表时都会刷新新的(和现有的)约会数据。
我需要确保一切都按顺序完成,并且只有在前一个任务完成时才能完成。因此,必须在db.DeleteAll之后执行appointmentments.download()并且必须在var allAppointments = db.All()之后执行列表刷新;
我认为问题是约会.download()函数必须进行HTTP GET调用,然后保存结果,其他函数不会等到它完成。
以下是代码:
btnReload.addEventListener('click', function(e){
var affected = db.deleteAll();
appointments.download();
var allAppointments = db.all();
Ti.API.info(allAppointments);
appointmentList.setData(allAppointments);
});
以下是被调用的函数:
db.deleteAll():
api.deleteAll = function(){
conn.execute('DELETE FROM appointments');
return conn.rowsAffected;
}
appointments.download():
var appointments = (function() {
var api = {};
api.download = function(){
var xhr = Titanium.Network.createHTTPClient();
xhr.onload = function()
{
var data = JSON.parse(this.responseText);
var dl = (data.length);
for(i=0; i<dl;i++)
{
//p = addRow(data,i); // returns the **arr array
//Ti.API.info('Saving : '+data[i].first_name);
var contact_name = data[i].first_name + ' ' + data[i].last_name;
var start_date = data[i].start_date;
var reference = data[i].reference;
var comment = data[i].comment;
var appointment_id = data[i].quote_id;
var lastid = db.create(appointment_id, start_date, reference, contact_name, comment);
//Ti.API.info(lastid);
}
};
xhr.open('GET','http://********.co.uk/appointments/download/');
xhr.send();
return;
}
最值得赞赏的任何帮助! 比利
答案 0 :(得分:1)
同步调用可以免费为您提供协调(代码不会执行任何依赖于完成的计算)。使用异步调用,您必须处理协调。这通常意味着将依赖代码作为函数传递给异步代码。传递的代码称为“continuation”,这意味着“剩余的计算,从给定的点开始”。传递延续被称为(不出所料)“continuation passing style”。
要在CPS中重写代码,请确定需要协调代码的点(对appointments.download
的调用),然后将其余代码包装在函数中。
btnReload.addEventListener('click', function(e){
var affected = db.deleteAll();
appointments.download();
function () {
var allAppointments = db.all();
Ti.API.info(allAppointments);
appointmentList.setData(allAppointments);
}
});
在一般情况下,返回值成为continuation的参数。这里没有使用appointments.download
的返回值,因此continuation不带参数。
接下来,重写异步函数以进行延续并在调用中传递延续。
btnReload.addEventListener('click', function(e){
var affected = db.deleteAll();
appointments.download(
function () {
var allAppointments = db.all();
Ti.API.info(allAppointments);
appointmentList.setData(allAppointments);
});
});
...
api.download = function(_return){
var xhr = Titanium.Network.createHTTPClient();
xhr.onload = function() {
var data = JSON.parse(this.responseText);
var dl = (data.length);
for (i=0; i<dl;i++) {
//p = addRow(data,i); // returns the **arr array
//Ti.API.info('Saving : '+data[i].first_name);
var contact_name = data[i].first_name + ' ' + data[i].last_name;
var start_date = data[i].start_date;
var reference = data[i].reference;
var comment = data[i].comment;
var appointment_id = data[i].quote_id;
var lastid = db.create(appointment_id, start_date, reference, contact_name, comment);
//Ti.API.info(lastid);
}
_return();
};
xhr.open('GET','http://********.co.uk/appointments/download/');
xhr.send();
return;
}
延续命名为_return
,因为return
语句可以建模为延续(默认延续)。在异步版本中调用_return
与在同步版本中调用return
具有相同的效果。
答案 1 :(得分:0)
目前您正在异步发出请求,这意味着您发出请求并立即从函数返回,您不会等待答案。您应该使您的呼叫同步,我不知道您的conn
和xhr
究竟是什么,但他们可能会提供使execute()
和send()
方法同步的方法。例如,如果您将JavaScript自己的XMLHttpRequest
的{{1}}方法的第三个参数设置为open()
,那么false
方法将不会返回,直到从服务器收到响应,连接类可能有相同的选项。
答案 2 :(得分:0)
移动调用以将当前约会删除到onload处理程序中。这样你就会删除旧的并立即添加新数据。