如何从第二个knex查询内部的knex查询访问变量?

时间:2019-01-11 22:32:51

标签: javascript mysql node.js knex.js

我有以下路线要获取与从第一个查询获得的ID相关的总和

app.post('/VerEmpresas', function (req, res) {

  var r, dot, ide;

  knex.from('empresas').select("id", "rut", "empresa", "razon_social", "email")
    .then((rows) => {
      for (row of rows) {

        ide = row['id'];

        knex.from('sucursales').sum("dotacion as SUM").where('id_empresas', '=', ide)
          .then((q0) => {

            dot = q0[0].SUM;
            console.log(dot);
          })
        console.log(dot);
        // do something here with dot

      }

      res.send();
    })
})

第一个console.log显示正确的值,但是第二个console.log显示未定义。如何在then()之外使用变量?

1 个答案:

答案 0 :(得分:0)

使用then时,您正在处理异步代码,这意味着程序遵循的路径不是线性的。您可以了解有关如何从异步调用here返回值的更多信息。

在您的情况下,第二个console.log在定义点之前运行。这听起来可能很奇怪,但是在第二个console.log运行时,数据库调用只是没有完成。为了在定义点之后使用点值,必须将另一个then链接到同一链。像这样:

app.post('/VerEmpresas', function (req, res) {

  var r, dot, ide;

  knex.from('empresas').select("id", "rut", "empresa", "razon_social", "email")
    .then((rows) => {
      for (row of rows) {

        ide = row['id'];

        knex.from('sucursales').sum("dotacion as SUM").where('id_empresas', '=', ide)
          .then((q0) => {

            dot = q0[0].SUM;
            console.log(dot);
          })
          .then(() => {
            console.log(dot);
            // do something here with dot
          })
      }

      res.send();
    })
})

第二个then在第一个之后运行。通常,您在带有返回值和参数的then之间传递结果,但是在您的情况下,您在函数顶部用var声明了dot,从而使结果可用。

您的代码还有另外两个问题,但这超出了此问题的范围:

  1. 您在循环内有异步调用。这可能会导致问题,因为循环可以立即启动所有异步调用。详细了解该here。我建议您切换到异步/等待,这是编排异步调用以使其看起来像同步代码的另一种方法。

  2. 您正在混合使用SQL和普通JavaScript。在这种情况下,这可能就是您想要的,但是通常要用SQL编写整个查询。特别是for循环看起来很奇怪。循环遍历第一个查询的整个结果基本上与选择相同。