두 개의 다른 함수에서 배열을 가져 오려고합니다. 이러한 함수는 데이터베이스에서 일부 쿼리를 수행합니다.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);
:
이 질문은 [Javascript가 올바르게 실행되지 않는다는 약속과 중복됩니까? {{각 ...}}을 (를) 사용하여 JQuery tmpl의 두 객체.] (http://stackoverflow.com/q/26994436/1960455)? 질문에 대한 차이점이 무엇인지는 분명하지 않습니다. –
귀하의 의견을 이해합니다. 실제로는 복제본이 아니지만 관련성이 있습니다. 다른 질문을 게시했을 때 jQuery-tmpl과 관련이 있다고 생각했습니다. 피드백을받지 못했기 때문에 나는 새로운 접근법으로 그것을 되풀이했다. 이 일을해서는 안된다는 것을 이해합니다. –
이것은 문제를 일으키지는 않지만 알고 있어야합니다. 'bookings.editBookPaxBuyPrepare (productId) .done (...)'을 할 수 있습니다. 그 주위에'$ .when()'이 필요 없습니다. '$ .when()'는 둘 이상의 약속이 있고 모두 완료되었을 때 통보 받기를 원할 때만 필요합니다. 그렇지 않으면,'.then()'또는'.done()'을 직접 사용하면된다. – jfriend00