【问题标题】:knex two mysql query synchronize using promiseknex 两个mysql查询使用promise同步
【发布时间】:2018-04-07 16:46:12
【问题描述】:
Promise.all(sendData.franchisee.map(row => {

    return  knex('designer.settings').select('value').where({setting_key : 'PRICING_TIER'})
            .then(pricing_tier => {

                row.pricing_tier = pricing_tier[0].value;

                knex('designer.pricing_tier').select('tier_title').where({id : row.pricing_tier})
                .then(tier_title =>{

                    row.tier_title = tier_title[0].tier_title;
                    return row;
                })

            });

})).then(response => {
    cb(sendData);     
});

在 promise 'designer.settings' 和 'designer.pricing_tier' 中听到两个查询。 当执行“designer.settings”时,我在执行“designer.pricing_tier”后得到了行中的结果,但输出没有出现在行中。 row.tier_title = tier_title[0].tier_title 不在最终的 sendData 中。 如何在一个 Promise 中同步两个查询?

【问题讨论】:

    标签: mysql node.js express promise knex.js


    【解决方案1】:

    不确定查询是否真的做完全相同的事情,但这只是演示了如何使用 knex 正确执行上述查询的基本思想。

    与加入定价层以防止需要 2 个单独的查询实际上是相同的。

    Promise.all(
      sendData.franchisee.map(row => {
        return knex('pricing_tier') 
          .withSchema('designer') // <-- selecting schema correctly in knex
          // this join could have been done as a subquery in select too...
          .join('settings', 'settings.setting_key', knex.raw('?', ['PRICING_TIER'])) 
          .select('settings.value', 'pricing_tier.tier_title')
          .where('pricing_tier.id', row.pricing_tier)
          .then(rows => {
            row.pricing_tier = rows[0].value;
            row.tier_title = rows[0].tier_title;
            return row;
          });
      })
    ).then(response => {
      cb(sendData); // <--- generally bad idea to mix promises and callbacks
    });
    

    生成的 SQL 是这样的:

    select 
      `settings`.`value`, 
      `pricing_tier`.`tier_title` 
    from `designer`.`pricing_tier` 
    inner join `designer`.`settings` on `settings`.`setting_key` = 'PRICING_TIER' 
    where `pricing_tier`.`id` = 3219
    

    【讨论】:

      【解决方案2】:

      您应该将两个查询包装到一个承诺中,该承诺只有在两个查询都完成了这样的工作时才会解析:

      Promise.all(sendData.franchisee.map(row => {
      
        return  new Promise((resolve) => {
          knex('designer.settings').select('value').where({setting_key : 'PRICING_TIER'})
            .then(pricing_tier => {
      
              row.pricing_tier = pricing_tier[0].value;
      
              knex('designer.pricing_tier').select('tier_title').where({id : row.pricing_tier})
                .then(tier_title =>{
      
                  row.tier_title = tier_title[0].tier_title;
                  resolve(row);
                })
      
            });
        });
      
      })).then(response => {
        cb(sendData);
      });
      

      【讨论】:

      • 这样更好,但仍然不必要的复杂,并且无法进行正确的错误处理。
      猜你喜欢
      • 1970-01-01
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-11
      • 2014-07-28
      • 1970-01-01
      • 2023-03-28
      • 2017-06-06
      相关资源
      最近更新 更多