2014-11-23 2 views
0

두 개의 다른 함수에서 배열을 가져 오려고합니다. 이러한 함수는 데이터베이스에서 일부 쿼리를 수행합니다.Javascript & JQuery : 예기치 않은 순서로 실행하겠다고 약속합니다.

문제는 트랜잭션의 비동기 특성과 관련이 있다고 생각합니다.

모든 절차를 성공하지 못하게하려고 여러 가지 방법을 시도했습니다.

I 거 상세히 오브젝트 생성하는 코드의 조각 :

예상 오브젝트 형태 :

[ 
    { 
     row: 
      { 
       prit_cd_item: 7, 
       prit_st_name: "1105 - Jazzboat" 
      }, 
     tariffs: 
      [ 
       { 
        cdPricing: 14, 
        dsPricing: "Operator tariff" 
       } 
      ] 
    } 
] 

기능 getTariffByProductItem :

getTariffByProductItem: function(productItemId) { 
    // Return Array of tariffs 
    var def = new $.Deferred(); 
    var tariffs = []; 
    db.transaction(function(tx) { 
     tx.executeSql('select pric.pric_cd_pricing, pric.pric_ds_pricing ' + 
         'from tga_pricings pric ' + 
         'where date(\'now\') <= pric.pric_dt_valid_to ' + 
         'and date(\'now\') >= pric.pric_dt_valid_from ' + 
         'and pric.pric_cd_product_item = ?', 
     [productItemId], 
     function(tx,dbResult) { 
      if(dbResult.rows.length) { 
       for(var i = 0; i < dbResult.rows.length; i++) { 
        tariffs.push( 
         { 
          cdPricing: dbResult.rows.item(i).pric_cd_pricing, 
          dsPricing: dbResult.rows.item(i).pric_ds_pricing 
         } 
        ); 
       } 
       def.resolve(tariffs); 
      } 
     }); 
    } 
    , function(e) { 
     alert("There has been an error: " + e.message); 
     def.reject(); 
    }); 

    return def.promise(); 
} 

기능 editBookPaxBuyPrepare :

editBookPaxBuyPrepare: function(productId) { 
var def = new $.Deferred(); 
var bookingId = $('#edit-book-pax-pricing-form').data('bookid'); 
var paxId = $('#edit-book-pax-pricing-form').data('paxid'); 
var productItems = []; 

// Check for actual data 
db.transaction(function(tx) { 
    // Get product items for product 
    tx.executeSql('select prit.prit_cd_item, prit.prit_st_name ' + 
        'from tga_products_catalog prod ' + 
        'inner join tga_product_items prit ' + 
        'on prit.prit_cd_product = prod.prod_cd_product ' + 
        'where prod.prod_cd_product = ?', 
    [ productId ], 
    function(tx, dbResult) { 
     if(dbResult.rows.length) { 
      // Set form action to EDIT 
      $('#edit-book-pax-buy-form').data('formaction', 'edit'); 
      // Set product name label 
      $('#edit-book-pax-buy-product').text(dbResult.rows.item(0).prod_ds_product); 
      for(var i=0; i<dbResult.rows.length; i++) { 
       // For each producItem get tariffs 
       var dbRow = dbResult.rows.item(i); 
       var data = []; 

       $.when(bookings.getTariffByProductItem(dbRow.prit_cd_item)) 
       .then(function(data) { 
        console.log("Product Item: " + dbRow.prit_st_name + " - tariffsArray: " + JSON.stringify(data)); 
        productItems.push({ "row": dbRow, "tariffs": data }); 
       }); 
      } 
      def.resolve(productItems); 
     } 
    }); 

}, 
function(e) { 
    def.reject(e); 
}); 
return def.promise(); 

}

메인 코드를 호출 위의 기능을 모두 :

var listFieldset = $('#edit-book-pax-buy-form-product-items-list'); 
listFieldset.empty(); 
$.when(bookings.editBookPaxBuyPrepare(productId)) 
.done(function(productItems) { 
    console.log(JSON.stringify(productItems)); 
    $("#edit-book-pax-buy-product-item").tmpl(productItems).appendTo(listFieldset); 
    listFieldset.trigger('create'); 
    listFieldset.listview('refresh'); 
}); 

로그 내가 얻을 :

bookings.js:738 [] 
2014-11-23 20:03:06.151bookings.js:566 Product Item: 1105 - Local guide - tariffsArray: [{"cdPricing":7,"dsPricing":"Operator tariff"}] 
2014-11-23 20:03:06.155bookings.js:566 Product Item: 1105 - Local guide - tariffsArray: [{"cdPricing":14,"dsPricing":"Operator tariff"}] 
2014-11-23 20:03:06.159bookings.js:566 Product Item: 1105 - Local guide - tariffsArray: [{"cdPricing":15,"dsPricing":"Operator tariff"}] 
2014-11-23 20:03:06.163bookings.js:566 Product Item: 1105 - Local guide - tariffsArray: [{"cdPricing":16,"dsPricing":"Operator tariff"}] 

당신은() JSON.stringify (productItems), "CONSOLE.LOG을 볼 수 있듯이 ; " editBookPaxBuyPrepare 함수 안에있는 loop의 console.log 행보다 먼저 실행됩니다. 예상되는 동작은 다른 방법입니다 : editBookPaxBuyPrepare가 끝날 때까지 기다린 후 returndes 배열의 내용을 약속에 기록하십시오.

내가 기대하는 것은 :

  • 전화 editBookPaxBuyPrepare은, (각 행에 하나씩) 제품 항목을 얻을.
  • 모든 행 (제품 항목)에 대해 for 루프 반복마다 getTariffByProductItem을 호출하는 관세 배열을 가져옵니다.
  • 개체가 올바르게 만들어지면 주 프로그램으로 돌아갑니다.

나는 이것을 돕기 위해 좋은 눈이 필요합니다.

도움이되었습니다.

감사합니다. 당신은 비동기입니다 $.when(bookings.getTariffByProductItem(dbRow.prit_cd_item))을 가지고 루프를 차단하지 않을 때문에 전후에 실행되고, 당신은 직접 루프의 루프 후하지만 내부 def.resolve(productItems); 전화

for(var i=0; i<dbResult.rows.length; i++) { 
    // For each producItem get tariffs 
    var dbRow = dbResult.rows.item(i); 
    var data = []; 

    $.when(bookings.getTariffByProductItem(dbRow.prit_cd_item)) 
    .then(function(data) { 
     console.log("Product Item: " + dbRow.prit_st_name + " - tariffsArray: " + JSON.stringify(data)); 
     productItems.push({ "row": dbRow, "tariffs": data }); 
    }); 
} 
def.resolve(productItems); 

:

+0

이 질문은 [Javascript가 올바르게 실행되지 않는다는 약속과 중복됩니까? {{각 ...}}을 (를) 사용하여 JQuery tmpl의 두 객체.] (http://stackoverflow.com/q/26994436/1960455)? 질문에 대한 차이점이 무엇인지는 분명하지 않습니다. –

+0

귀하의 의견을 이해합니다. 실제로는 복제본이 아니지만 관련성이 있습니다. 다른 질문을 게시했을 때 jQuery-tmpl과 관련이 있다고 생각했습니다. 피드백을받지 못했기 때문에 나는 새로운 접근법으로 그것을 되풀이했다. 이 일을해서는 안된다는 것을 이해합니다. –

+0

이것은 문제를 일으키지는 않지만 알고 있어야합니다. 'bookings.editBookPaxBuyPrepare (productId) .done (...)'을 할 수 있습니다. 그 주위에'$ .when()'이 필요 없습니다. '$ .when()'는 둘 이상의 약속이 있고 모두 완료되었을 때 통보 받기를 원할 때만 필요합니다. 그렇지 않으면,'.then()'또는'.done()'을 직접 사용하면된다. – jfriend00

답변

1

당신의 문제는이 코드의 일부입니다 def.resolve(productItems);

또 다른 문제는 루프가 완료된 후 실행되는 .then() 콜백 모두에 대해 이 동일하다는 것입니다.

당신은 내가 완벽한 약속 라이브러리가 아닌 jQuery를 사용하는 것이 좋습니다 것, 모든 코드를 통해 (루프 포함) 복잡한 방법으로 약속을 사용하려는 경우.

+0

답변 해 주셔서 감사합니다. 어떤 도서관에 대한 제안? 나는 Cordova로 jQuery Mobile 앱을 개발하고있다. Q 또는 언제보고 있습니다. –

+0

@ JoséLuisGallego'when '으로 시작했지만 현재 모든 프로젝트에서'bluebird '를 사용하도록 마이그레이션되었습니다. 개인적으로 나는 그것이 더 나은 선택이라고 생각한다. 다른 점은 bluebird가 문서의 접두어로'Promise.'를 사용한다는 것입니다. 현재 브라우저에서 네이티브 방식으로 사용할 때처럼'when'은'when.'을 접두사로 사용합니다. _prefix_를 직접 선택할 수도 있지만 제 생각에는 공급 업체 이름을 문서의 표준에 대한 접두사로 사용하는 것은 나쁜 선택입니다. –

관련 문제