数据库表的客户端异步连接

时间:2015-10-24 22:13:12

标签: angularjs node.js promise

这一整天我都在试图解决这个问题。

我正在尝试从angularJS应用程序从sqlite数据库中提取实体树,使用nodejs作为运行客户端生成的SQL查询的填充程序。我也在使用underscore.js。

我可以通过使用连接将实体展平为类似于表的结构(不包含其他对象的对象数组),并将行“膨胀”为嵌套对象和客户端数组,但我想了解承诺。我可以使用Spring与Hibernate和JPA,将JSON传递给服务器,但这是一个实验。我知道它在很多层面都不是最佳的。

问题

tableA包含类型A的实体。表B和C相同。数据库中的关系是:A有一组B.每个B都与C配对。所以,如果我使用Hibernate和Spring,我可以问一下对于A,服务器将使用A数组进行响应,每个项目包含一个B数组,并且avery包含一个C.

我的实施

我希望函数'getAObjectDeep'返回一个promise,当我在promise上调用success(回调)时,回调传递一个A类实体列表,每个实体包含一个B类实体数组,而后者又包含C类匹配实体。

这是我写的代码,但不起作用。问题是,当我在第二个promise中调用$ q.all时,所有类型为A的实体都会丢失,并且响应会填充一个B类实体数组,当我在$中调用$ q.all时第三个承诺,B类的所有实体都丢失了,响应中填充了一个'undefined'数组。 我无法控制$ q.all的输出,将前一个promise的值传递给下一个promise,并从数据库中获取新行。

var queryDb = function(query) {
    return $http.get('/', {params: {sql: query}});
};

var getAObjectDeep = function(start, end) {
    return queryDb('SELECT * FROM tableA WHERE tableA.date >= \'' + start + '\' AND tableA.date <= \'' + end + '\' ORDER BY date DESC;')
    .then(function(response) {
        return $q.all(_.map(response.data, function(entityA) {
            return _.extend(entityA, queryDb('SELECT * FROM tableB WHERE idEntityA=' + entityA.id + ';'));
        }));
    })
    .then(function(response) {
        return $q.all(_.map(response, function(r) {
            var entityB = r.data;
            return _.extend(entityB, queryDb('SELECT * FROM tableC WHERE id=' + entityB.idObjB));
        }));
    });
}

1 个答案:

答案 0 :(得分:1)

不要忘记queryDb()将在所有三种情况下都返回一个承诺,并且只能通过承诺方法访问响应,而不是直接访问。

首次使用queryDb()会显示正确的模式:

queryDb(...)
.then(function() {
    ...
});

但是第二次和第三次使用似乎都假定了一个数组 - 无论如何_.extend()将会运行。

据我所知,你需要将两个最里面的表达式“由内向外”转换,然后引入一个.then()

var getAObjectDeep = function(start, end) {
    return queryDb('SELECT * FROM tableA WHERE tableA.date >= \'' + start + '\' AND tableA.date <= \'' + end + '\' ORDER BY date DESC;')
    .then(function(response) {
        return $q.all(_.map(response.data, function(entityA) {
            return queryDb('SELECT * FROM tableB WHERE idEntityA=' + entityA.id + ';').then(function(response2) {
                return _.extend(entityA, response2);
            });
        }));
    })
    .then(function(response) {
        return $q.all(_.map(response, function(r) {
            var entityB = r.data; //???
            return queryDb('SELECT * FROM tableC WHERE id=' + entityB.idObjB).then(function(response3) {
                return _.extend(entityB, response3);
            });
        }));
    });
}

从async / promise角度来看,原始代码的这种转换更有意义。

“加入”逻辑与问题中的逻辑相同。没有尝试验证它,除了说var entityB = r.data可能不正确,因为@vbranden指出;如果不起作用,请尝试var entityB = r