Nodejs结合了我的sql命令的两个结果

时间:2016-08-11 15:26:38

标签: javascript node.js

我有两个mySql命令作为从数据库获取结果,我试图用下面的代码获取它们但它没有正常工作

例如:

userEwallets表中获取结果:

function getMoneySenderUserInfo(data, callback) {
    var sourceEwalletNumber = data.transferToEwallet.substring(0, 5) + data.registeredMobileNumber.substring(1, data.registeredMobileNumber.length);
    var query               = "SELECT userEwallets.id as ewalletId, users.id as userId , money_repositories.money as money FROM userEwallets " +
                              "JOIN users ON users.id = userEwallets.userId " +
                              "JOIN money_repositories ON userEwallets.id = money_repositories.ewalletId " +
                              "WHERE ewalletNumber = '" + sourceEwalletNumber + "' ";
    connection.query(query, function (err, results) {
        if (err) return callback(false);

        if (results.length === 0) return callback(false);

        callback(true, results[0]);
    });
}

再次从userEwallets表中获取结果以获得其他结果:

function getDestinationTakeMoneyUserInfo(data, callback) {
    var query = "SELECT users.id as userId FROM userEwallets " +
                "JOIN users ON users.id = userEwallets.userId " +
                "WHERE ewalletNumber = '" + data.transferToEwallet + "' ";
    connection.query(query, function (err, results) {
        if (err) return callback(false);

        if (results.length === 0) return callback(false);

        callback(true, results[0]);
    });
}

现在我想将此结果与此代码结合使用:

usersInformation = {};
getMoneySenderUserInfo(data, function (success, result) {
    if (success) {
        usersInformation['senderId']  = result.userId;
        usersInformation['ewalletId'] = result.ewalletId;
        usersInformation['money']     = result.money;
        getDestinationTakeMoneyUserInfo(data, function (success, result) {
            usersInformation['destinationUserId'] = result.userId;
        });
    }
    log.info(usersInformation);
});

2 个答案:

答案 0 :(得分:2)

您应该使用Promise

我举个例子

function getMoneySenderUserInfo(data) {

 var promise = new Promise( function(resolve, reject) {
   var query = "..."
   connection.query(query, function (err, results) {
     if (err || results.length === 0) {
       reject();
     } else {
       resolve(results[0]);
     }
   });

 return promise;
}

你必须对getDestinationTakeMoneyUserInfo函数

做同样的事情

然后你可以得到这样的最终结果:

var usersInformation = {};
Promise.all([getMoneySenderUserInfo(data), getDestinationTakeMoneyUserInfo(data)])
.then(function (results) {
    usersInformation['senderId']  = results[0].userId;
    usersInformation['ewalletId'] = results[0].ewalletId;
    usersInformation['money']     = results[0].money;
    usersInformation['destinationUserId'] = result[1].userId;
});

正如您所看到的,Promise.all将等待两个db请求,当两个promise将被解析时,将调用回调(在then函数中传递),这样您最终可以检索这两个结果

你也可以链接这样的承诺:

getMoneySenderUserInfo(data)
.then(function (result) {
    usersInformation['senderId']  = result.userId;
    usersInformation['ewalletId'] = result.ewalletId;
    usersInformation['money']     = result.money;
    return getDestinationTakeMoneyUserInfo(data);
}).then(function (result) {
    usersInformation['destinationUserId'] = result.userId;
});

答案 1 :(得分:1)

您遇到的问题是从数据库获取数据异步。这就是你必须使用回调函数来处理结果的原因。

让我们来看一下你的函数getMoneySenderUserInfo。当您调用它时,它会使用您的SQL查询调用connection.query,然后继续到该函数中的下一条指令。然后,在该函数完成后的某个时间点,您的SQL库将接收查询结果,并调用您的回调。

将此应用于最终代码,在函数底部调用log.info(usersInformation)不会包含destinationUserId,因为尚未使用结果调用回调。< / p>

如果您将log.info来电转移到getDestinationTakeMoneyUserInfo的回调中,那么您将获得预期的结果。

getMoneySenderUserInfo(data, function (success, result) {
    // This happens first
    if (success) {
        usersInformation['senderId']  = result.userId;
        usersInformation['ewalletId'] = result.ewalletId;
        usersInformation['money']     = result.money;
        getDestinationTakeMoneyUserInfo(data, function (success, result) {
            // This (probably) happens third
            usersInformation['destinationUserId'] = result.userId;
        });
    }

    // This happens second
    log.info(usersInformation);
});

如果您有兴趣或想了解更多有关这一切的信息,请查看Philip Roberts的this fantastic video