2011-08-26 8 views
1

티타늄 앱을 쓰고 있는데 자바 스크립트의 실행 순서에 문제가 있습니다.자바 스크립트 : 함수의 순서 설정

버튼에 이벤트 리스너가 있습니다. 테이블을 지우고 HTTPClient를 사용하여 '약속'의 JSON 배열을 가져와 각 약속을 저장하고 테이블 목록을 새로 고치는 다시로드 버튼입니다. 문제는 내가 테이블을 지워야하는 테이블 삭제를 먼저 실행하고 있습니다. 그런 다음 약속을 얻습니다.하지만 앱이 데이터 테이블을 새로 고침하면 너무 빨리 처리되고 새 약속이 저장되지 않은 것 같습니다. 빈 목록. 이제 db.deleteAll 행을 주석 처리하면, 새로 고침을 클릭 할 때마다 새 (및 기존) 약속 데이터로 목록이 새로 고쳐집니다.

이전 작업이 완료되었을 때만 모든 것이 순서대로 이루어 졌는지 확인해야합니다. 따라서 db.DeleteAll 후에도 appointments.download()를 실행해야하고 목록 새로 고침을 수행해야합니다. var allAppointments = db.All();

나는 문제는 appointments.download() 함수가 HTTP GET 호출을 만들어 결과를 저장하고 다른 함수가 끝날 때까지 기다리지 않는다는 것입니다.

db.deleteAll() :

api.deleteAll = function(){ 
    conn.execute('DELETE FROM appointments'); 
    return conn.rowsAffected; 
} 

appointments.download() : 여기

btnReload.addEventListener('click', function(e){ 
    var affected = db.deleteAll(); 
    appointments.download(); 
    var allAppointments = db.all(); 
    Ti.API.info(allAppointments); 
    appointmentList.setData(allAppointments); 
}); 

호출되는 함수이다 : 여기

코드이다

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; 
} 

가장 높이 평가! 빌리

답변

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); 
    } 
}); 

일반적으로 반환 값은 연속의 인수가됩니다.여기서 appointments.download에 대한 반환 값이 사용되지 않으므로 연속에 인수가 필요하지 않습니다.

다음으로 비동기 함수를 다시 작성하여 계속 작업을 수행하고 통화에서 계속을 전달하십시오. return 문이 계속 (기본 지속)으로 모델링 할 수 있기 때문에

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을 호출하는 것과 동일한 영향을 미칩니다.

+0

감사합니다! 이것은 정말 잘 작동했고 CPS에 대한 설명에 감사드립니다! – iamjonesy

0

현재 요청을 비동기 적으로 수행하고 있습니다. 즉, 요청을 받고 즉시 함수에서 돌아 오면 응답을 기다리지 않습니다. 귀하의 전화를 동기로 만들어야하는데, 귀하의 connxhr이 실제로 무엇인지는 모르지만 execute()send() 방법을 동기화하는 방법을 제공 할 수 있습니다. 예를 들어, JavaScript 자체의 세 번째 인수 인 XMLHttpRequestopen() 메서드를 false으로 설정하면 send() 메서드는 서버에서 응답을받을 때까지 반환되지 않으며 연결 클래스에도 동일한 옵션이있을 수 있습니다.

+0

요청을 동기식으로 만드는 것은 나쁜 생각입니다. 요청이 완료 될 때까지 모든 JS 호출을 차단합니다. 이로 인해 브라우저 UI가 응답을 멈추게되어 매달아 진 모양을 갖게됩니다. – outis

0

현재 약속을 삭제하라는 호출을 onload 처리기로 이동합니다. 그렇게하면 이전 데이터를 삭제하고 즉시 새 데이터를 추가합니다.