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