Nodejs 巢状函数的匿名函数的回传问题

Nodejs 巢状函数的匿名函数的回传问题

前辈们午安,

小弟尝试在连结 MySQL 时遇到了一些小问题。

问题如下:

我想要将 dbclient.query 的结果回传给呼叫 GetUsers() 的程式码,

但因为 dbclient.query 的 rows 仅存在于匿名函数(lambda)之中。

GetUsers = function () {
	dbclient.query("SELECT * FROM user", function (err, rows) {
		for (var i = 0 ; i < rows.length ; i++)
			console.log(rows[i].uid + " " + rows[i].email);
	});
}

GetUsers();

如今我想要将 SQL query 的结果给挪到外部使用,

但我不大想使用全域变数(global)暴力解决,

请问前辈们有什么建议吗?

GetUsers = function () {
	dbclient.query("SELECT * FROM user", function (err, rows) {
		return rows;
	});
}

rows = GetUsers();


3 回复

当然可以!让我们通过示例代码来解释如何处理这个问题。在 Node.js 中,由于异步编程的特性,我们不能直接从回调函数中返回数据。我们需要使用回调函数或 Promise 来处理这种情况。

示例代码

首先,我们可以通过回调函数来处理 dbclient.query 的结果:

const dbclient = require('./dbclient'); // 假设你有一个数据库客户端

// 定义一个函数,接受一个回调函数作为参数
GetUsers = function (callback) {
    dbclient.query("SELECT * FROM user", function (err, rows) {
        if (err) {
            return callback(err); // 如果有错误,传递错误
        }
        callback(null, rows); // 没有错误时,传递查询结果
    });
};

// 调用 GetUsers 函数,并传入一个回调函数来处理结果
GetUsers(function (err, rows) {
    if (err) {
        console.error("Error:", err);
        return;
    }
    for (var i = 0; i < rows.length; i++) {
        console.log(rows[i].uid + " " + rows[i].email);
    }
});

// 你可以在这里继续你的逻辑

使用 Promise

如果你更喜欢使用 Promise,可以这样写:

const dbclient = require('./dbclient');

// 定义一个返回 Promise 的函数
GetUsers = function () {
    return new Promise((resolve, reject) => {
        dbclient.query("SELECT * FROM user", function (err, rows) {
            if (err) {
                return reject(err); // 如果有错误,拒绝 Promise
            }
            resolve(rows); // 没有错误时,解析 Promise
        });
    });
};

// 调用 GetUsers 函数,并使用 .then 和 .catch 来处理结果
GetUsers()
    .then(rows => {
        for (var i = 0; i < rows.length; i++) {
            console.log(rows[i].uid + " " + rows[i].email);
        }
    })
    .catch(err => {
        console.error("Error:", err);
    });

// 你也可以在这里继续你的逻辑

解释

  1. 回调函数:在第一个示例中,我们定义了一个接受回调函数的 GetUsers 函数。当查询完成时,我们将结果传递给回调函数。这种方式是 Node.js 中处理异步操作的一种常见方法。

  2. Promise:在第二个示例中,我们使用了 Promise。这使得代码更加简洁,并且可以更容易地进行链式调用。Promise 使异步代码看起来更像同步代码,提高了可读性和可维护性。

这两种方法都可以有效地处理异步查询的结果,避免了全局变量的使用。希望这些示例能帮助你解决问题!


GetUsers = function (callback) {
    dbclient.query("SELECT * FROM user", function (err, rows) {
        callback(rows);
    });
}
GetUsers(function (rows) {
 // here is your rows.
});

在这个例子中,dbclient.query 是一个异步操作,因此直接返回 rows 并不能达到预期的效果。你需要使用回调函数来处理异步操作的结果。

以下是一个改进后的示例:

GetUsers = function (callback) {
    dbclient.query("SELECT * FROM user", function (err, rows) {
        if (err) {
            callback(err, null);
            return;
        }
        for (var i = 0; i < rows.length; i++) {
            console.log(rows[i].uid + " " + rows[i].email);
        }
        callback(null, rows);
    });
};

// 调用 GetUsers 函数并传递回调函数
GetUsers(function (err, result) {
    if (err) {
        console.error("Error fetching users:", err);
        return;
    }
    // 在这里处理查询结果
    console.log("Users fetched successfully:", result);
});

解释:

  1. 回调函数:我们将 GetUsers 函数修改为接受一个回调函数作为参数。这样可以在 dbclient.query 操作完成后执行回调函数,并将查询结果传递回去。
  2. 错误处理:在回调函数中处理可能出现的错误。
  3. 外部处理:在调用 GetUsers 时,传递一个回调函数来处理查询结果。

这种方法避免了使用全局变量,并且能更好地处理异步操作的结果。

回到顶部