2017-09-15 116 views
2

我使用knex链接查询将其他数据添加到我的JSON返回对象。然而,我似乎无法理解为什么我不能将一个knex.query的检查传递给第二个knex查询的.then()。Javascript - 将先前的查询结果传递到下一个.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); 
    }); 
    }) 
} 

这是我完整的代码,你可以看到我想要查询的应用程序表,.then()环比结果然后查询Apps_features表,然后注入功能结果转换为原始查询结果。我收到一条错误消息。

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

回答

2

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

这个周期将被立即执行:

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

所以i将等于results[0].length当内承诺都得到了解决。 您可以轻松地测试它试图将其指定为静态的检查,如果它的工作原理:

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

为了解决这个问题,你必须电流i传递给内承诺的调用和返回值,以便在解决承诺时不使用已经设置的最大值。

所以,你可以这样做:

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

是有道理的,但IM仍然相当新的节点,如何将我去这样做? – Charles

+0

很抱歉,但您的回答让我困惑如何去实施您的解决方案 – Charles

+0

在这些情况下,最好的方法是,您在调用的函数内部管理'i'值,并在解析的promise中将它与'features'一起返回。但你允许在特定呼叫中工作'db.raw(' SELECT * FROM APPs_Features WHERE VARAPP_ID =? ORDER BY VARAPP_ORDER ASC ',结果[0] [I] .VARAPP_ID])'? – quirimmo

相关问题