我正在尝试从两个不同的函数中获取一组对象。这些函数在数据库中执行一些查询。
我认为问题与交易的异步性质有关。
我尝试了几种替代方案,尝试使所有程序同步但没有成功。
我将详细介绍生成对象的代码片段:
预期的物体形状:
[
{
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"}]
如您所见,“console.log(JSON.stringify(productItems));”在editBookPaxBuyPrepare函数内的循环中的console.log行之前执行。预期的行为是相反的:等到editBookPaxBuyPrepare完成,然后在promise中记录returndes数组的内容。
我的期望是:
我需要一些善良的眼睛来帮助我。
欢迎任何帮助!
感谢。
答案 0 :(得分:1)
你的问题是代码的这一部分:
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);
你在循环之后直接调用def.resolve(productItems);
但在循环内部你有$.when(bookings.getTariffByProductItem(dbRow.prit_cd_item))
这是异步的并且不会阻止循环因此在你调用def.resolve(productItems);
<之后执行/ p>
另一个问题是dbRow
对于所有.then()
回调都是相同的,因为这些回调在循环结束后执行。
如果您计划在代码中以复杂方式(包括循环)使用Promises,那么我建议使用完整承诺库而不是jQuery。