Javascript&;JQuery:承诺以意外顺序执行
我试图从两个不同的函数中获得一个对象数组。这些函数在数据库中执行一些查询 我认为问题与事务的异步性质有关 我尝试了几种方法,试图使所有过程同步,但没有成功 我将详细介绍生成对象的代码片段: 预期的对象形状:Javascript&;JQuery:承诺以意外顺序执行,javascript,jquery,mysql,promise,javascript-objects,Javascript,Jquery,Mysql,Promise,Javascript Objects,我试图从两个不同的函数中获得一个对象数组。这些函数在数据库中执行一些查询 我认为问题与事务的异步性质有关 我尝试了几种方法,试图使所有过程同步,但没有成功 我将详细介绍生成对象的代码片段: 预期的对象形状: [ { row: { prit_cd_item: 7, prit_st_name: "1105 - Jazzboat" }, ta
[
{
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();
}
我得到的日志:
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完成,然后将returndes数组的内容记录在promise中
我所期望的是:
- 调用editBookPaxBuyPrepare,获取产品项(每行一个)
- 对于每一行(产品项),获取在每个For循环迭代中调用getTariffByProductItem的关税数组
- 正确创建对象后,返回主程序
谢谢。您的问题在于代码的这一部分:
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);
用于(var i=0;这是一个重复的to问题?这些to问题之间的区别不明显。我理解你的评论。这不是一个真正的重复,但它是相关的。当我发布另一个问题时,我认为它与jQuery tmpl有关。因为我没有收到任何反馈,所以我用新方法重写了它。我理解不应该这样做。这不会造成问题,但值得知道。您可以只进行预订。editBookPaxBuyPrepare(productId)。完成(…)
。您不需要$.when()
围绕它。$.when()只有当您有多个承诺并且希望在所有承诺都完成时收到通知时,才需要使用。否则,只需使用.then()
或.done()
直接写在承诺上。谢谢你的回答。对任何库有什么建议吗?我正在用Cordova开发一个jQuery移动应用程序。我正在研究Q或when。@JoséLuisGallego我从开始时是的
,但目前将我所有的项目迁移到了蓝鸟
。我个人认为这是更好的选择。另外一点是蓝鸟在其文档中使用了Promise.
作为前缀,就像您在当前浏览器中本机使用它一样,when
在文档中使用when.
作为前缀。虽然您可以自己选择前缀,但在我看来,使用供应商名称作为前缀f是一个错误的选择或者文档中的标准。
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"}]
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);