简体   繁体   English

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

[英]How to access a variable from a knex query inside of a second knex query?

I have the following route where I want to get the sum associated to an id I get from the first query 我有以下路线,我想要从第一个查询获得的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();
    })
})

The first console.log show the correct value, but the second console.log shows undefined. 第一个console.log显示正确的值,但是第二个console.log显示未定义。 How do I get to use the variable outside of the then() ? 我如何在then()之外使用变量?

When you are using then , you are dealing with asynchronous code, which means the path the program follows isn't linear. 当您使用then ,您正在处理异步代码,这意味着程序遵循的路径不是线性的。 You can read more about how to return values from asynchronous calls here . 您可以在此处阅读有关如何从异步调用返回值的更多信息。

In your case, the second console.log is run before dot has been defined. 在您的情况下,第二个console.log在定义点之前运行。 That might sound strange, but the database call simply isn't finished by the time the second console.log has run. 这听起来可能很奇怪,但是在第二个console.log运行时,数据库调用只是没有完成。 In order to use the dot value after you define it, you have to chain another then to the same chain. 为了使用定义之后的点值,就得链中的另一个then在同一链。 Something like this: 像这样:

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

The second then is run after the first. 然后第二个在第一个then运行。 Usually, you pass results between then s with return and parameters but in your case, you have declared dot with var at the top of the function which makes it available that way. 通常情况下,你传递的结果之间then ,返回和参数秒,但在你的情况,你有这使得它获得这样的函数的顶部声明使用var点。

There are two more issues with your code, but it falls outside the scope of this question: 您的代码还有另外两个问题,但这超出了此问题的范围:

  1. You have async calls inside a loop. 您在循环内有异步调用。 This can cause issues as the loop can start all the async calls immediately. 这可能会导致问题,因为循环可以立即启动所有异步调用。 Read more about that here . 在这里阅读更多有关它的信息 I would advice you to switch to async/await, which is another way to orchestrate asynchronous calls in order to make it look like synchronous code. 我建议您切换到异步/等待,这是编排异步调用以使其看起来像同步代码的另一种方法。

  2. You are mixing SQL and ordinary JavaScript. 您正在混合使用SQL和普通的JavaScript。 This might be what you want in this case, but generally writing the entire query in SQL is the way to go. 在这种情况下,这可能就是您想要的,但是通常要用SQL编写整个查询。 Especially the for loop looks weird. 特别是for循环看起来很奇怪。 Looping over the entire result of the first query is basically the same as a select. 循环遍历第一个查询的整个结果基本上与选择相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM