Javascript - 将之前的查询结果传递给 next.then()

Javascript - Passing previous query results into next .then()

我正在使用 knex 链接查询以将额外数据添加到我的 JSON return 对象。但是我似乎无法理解为什么我不能将结果从一个 knex.query 传递到第二个 knex 查询的 .then()。

代码:

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

这是我的完整代码,如您所见,我正在尝试查询应用程序 table,.then() 循环结果然后查询 Apps_features table 然后将特征结果注入到原始查询结果中。我收到一条错误消息。

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

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

这个循环会立即执行:

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

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

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

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

所以你可以这样做:

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