在node.js中使用promise处理MySQL返回值

新手上路,请多包涵

我有 python 背景,目前正在迁移到 node.js。由于它的异步性质,我无法适应 node.js。

例如,我试图从 MySQL 函数返回一个值。

 function getLastRecord(name)
{
    var connection = getMySQL_connection();

    var query_str =
    "SELECT name, " +
    "FROM records " +
    "WHERE (name = ?) " +
    "LIMIT 1 ";

    var query_var = [name];

    var query = connection.query(query_str, query_var, function (err, rows, fields) {
        //if (err) throw err;
        if (err) {
            //throw err;
            console.log(err);
            logger.info(err);
        }
        else {
            //console.log(rows);
            return rows;
        }
    }); //var query = connection.query(query_str, function (err, rows, fields) {
}

var rows = getLastRecord('name_record');

console.log(rows);

经过一番阅读,我意识到上面的代码无法工作,由于 node.js 的异步特性,我需要返回一个承诺。我不能像 python 那样编写 node.js 代码。如何转换 getLastRecord() 以返回一个承诺以及如何处理返回的值?

事实上,我想做的是这样的;

 if (getLastRecord() > 20)
{
    console.log("action");
}

如何以可读的方式在 node.js 中完成?

我想看看在这种情况下如何使用蓝鸟实现承诺。

原文由 guagay_wk 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 702
2 个回答

这会有点散,见谅。

首先,假设这段代码正确地使用了 mysql 驱动 API,下面是一种你可以包装它以使用原生 promise 的方法:

 function getLastRecord(name)
{
    return new Promise(function(resolve, reject) {
        // The Promise constructor should catch any errors thrown on
        // this tick. Alternately, try/catch and reject(err) on catch.
        var connection = getMySQL_connection();

        var query_str =
        "SELECT name, " +
        "FROM records " +
        "WHERE (name = ?) " +
        "LIMIT 1 ";

        var query_var = [name];

        connection.query(query_str, query_var, function (err, rows, fields) {
            // Call reject on error states,
            // call resolve with results
            if (err) {
                return reject(err);
            }
            resolve(rows);
        });
    });
}

getLastRecord('name_record').then(function(rows) {
    // now you have your rows, you can see if there are <20 of them
}).catch((err) => setImmediate(() => { throw err; })); // Throw async to escape the promise chain

所以一件事:你仍然有回调。回调只是您将其交给某些东西以在未来某个时间调用的函数,并带有其选择的参数。因此 xs.map(fn) 中的函数参数、节点中看到的 (err, result) 函数以及 promise 结果和错误处理程序都是回调。人们将特定类型的回调称为“回调”,这有点混淆,即 (err, result) 在节点核心中以所谓的“连续传递样式”使用,有时被人们称为“nodebacks”真的不喜欢他们。

至少就目前而言(async/await 最终会到来),无论您是否采用 Promise,您几乎都被回调所困扰。

另外,我会注意到,promise 不是立即的,在这里显然很有帮助,因为你仍然有一个回调。只有当您将 Promise 与 Promise.all 和 promise accumulators a la Array.prototype.reduce 结合使用时,Promise 才会真正发挥作用。但它们 有时 确实会 发光,值得学习。

原文由 Josh Holbrook 发布,翻译遵循 CC BY-SA 3.0 许可协议

我修改了您的代码以使用 Q(NPM 模块) 承诺。我假设您在上面的代码片段中指定的“getLastRecord()”函数可以正常工作。

您可以参考以下链接获取Q模块

单击此处:Q 文档

var q = require('q');

function getLastRecord(name)
{

var deferred = q.defer(); // Use Q
var connection = getMySQL_connection();

var query_str =
"SELECT name, " +
"FROM records " +
"WHERE (name = ?) " +
"LIMIT 1 ";

var query_var = [name];

var query = connection.query(query_str, query_var, function (err, rows, fields) {
    //if (err) throw err;
    if (err) {
        //throw err;
        deferred.reject(err);
    }
    else {
        //console.log(rows);
        deferred.resolve(rows);
    }
}); //var query = connection.query(query_str, function (err, rows, fields) {

return deferred.promise;
}

// Call the method like this
getLastRecord('name_record')
 .then(function(rows){
   // This function get called, when success
   console.log(rows);
  },function(error){
   // This function get called, when error
   console.log(error);

 });

原文由 Piyush Sagar 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题