Javascript - 将以前的查询结果传递给下一个.then()

时间:2017-09-15 15:27:38

标签: javascript node.js knex.js

我使用knex链接查询以向JSON返回对象添加其他数据。但是我似乎无法理解为什么我不能将一个knex.query的结果传递给第二个knex查询的.then()。

CODE:

 exports.getApps = function() {
  return new Promise(function(resolve, reject) {
    db.raw(`
      SELECT *
      FROM APPs
      WHERE VARAPP_PUBLIC_ACTIVE > 0
      ORDER BY VARAPP_PUBLIC_ACTIVE ASC, VARAPP_NAME ASC
    `).then(function(results) {
      if (results[0].length > 0) {
          for (var i = 0; i < results[0].length; i++) {
            db.raw(`
              SELECT *
              FROM APPs_Features
              WHERE VARAPP_ID = ?
                ORDER BY VARAPP_ORDER ASC
            `, [results[0][i].VARAPP_ID], i)
            .then(function(features, currentIndex) {
              if (features[0].length > 0) {
                console.log(results[0]);
                console.log(features[0]);

                results[0][currentIndex].Features = features[0];
              } else {
                results[0][currentIndex].Features = null;
              }

            }).catch(function(err) {
              console.error(err);
              reject(err);
            });

          }

          resolve({
            apps: results[0]
          })
      } else {
        resolve({
          error: 'No Apps Found'
        })
      }
    }).catch(function(err) {
      console.error(err);
      reject(err);
    });
  })
}

这是我的完整代码,因为您可以看到我尝试查询apps表,.then()循环结果然后查询Apps_features表,然后将功能结果注入原始查询结果。我收到的错误是。

TypeError: Cannot set property 'Features' of undefined
    at C:\Sites\VARNET_Vars\content\appList.js:21:40

1 个答案:

答案 0 :(得分:2)

取决于i值,而不是链接。

此循环将立即执行:

for (var i = 0; i < results[0].length; i++)

当内部承诺得到解决时,i将等于results[0].length。 您可以轻松地测试它,尝试将其指定为静态以检查它是否有效:

results[0][i].Features = features[0];

为了修复它,你必须将当前的i传递给内部的promise调用和返回的值,以便在解析promises时不使用已经设置的最大值。

所以你可以这样做:

exports.getApps = function() {
  return new Promise(function(resolve, reject) {
    db.raw(`
      SELECT *
      FROM APPs
      WHERE VARAPP_PUBLIC_ACTIVE > 0
      ORDER BY VARAPP_PUBLIC_ACTIVE ASC, VARAPP_NAME ASC
    `).then(function(results) {
      if (results[0].length > 0) {
        for (var i = 0; i < results[0].length; i++) {
          elaborate(i, results, reject);   
        }
        resolve({
          apps: results[0]
        })
      } else {
        resolve({
          error: 'No Apps Found'
        })
      }
    }).catch(function(err) {
      console.error(err);
      reject(err);
    });
  })

  function elaborate(i, results, reject) {
    db.raw(`
              SELECT *
              FROM APPs_Features
              WHERE VARAPP_ID = ?
                ORDER BY VARAPP_ORDER ASC
            `, [results[0][i].VARAPP_ID], i)
      .then(function(features) {
        if (features[0].length > 0) {
          results[0][i].Features = features[0];
        } else {
          results[0][i].Features = null;
        }

      }).catch(function(err) {
        console.error(err);
        reject(err);
      });
  }
}