Nodejs程式码的异步处理问题(已解决)

Nodejs程式码的异步处理问题(已解决)

后续补充说明: 本函数想要处理的事情流程:

  1. 建立好query 的函数,SQL query 的结果以callback 方式。
  2. 呼叫刚刚建立好的函数。
  3. 等待回传完毕后观看是否有query 结果,再决定要回传T/F。

然而现在的函数遇到的问题,

不等待第二步骤的函数回传直接进行下一步骤(知道是因为异步执行),

导致不是回传「依照判断所回传的T/F」,因为没有注明此处会回传undefined。


尝试使用巢状函数(Nested)去解决它但仍无法,

因为 _SearchUser 函数已经异步执行去了。

(下面的 sample code 是原始程式码)


基本上非同步执行程式码是件相当好的一件事情,

但预设情况下还是单线程在撰写程式上还是比较习惯,

不晓得是不是nodeJS 擅自完成了这件事情,

发生了不在我预期内的结果。

还麻烦各位前辈指教。

SearchUser = function (email) {
	_SearchUser = function (callback) {
		dbclient.query("SELECT * FROM user WHERE email = \"" + email + "\"", function (err, isExist) {
			callback(isExist);
		});
	}
console.log("A");

_SearchUser(function (isExist) {

	console.log("B");

	console.log(isExist.length);
	if (isExist.length > 0)
		return true;
	else
		return false;
});

console.log("C");
// 此处尚未等到 _SearchUser 回传结果就率先回传本函数

}

出现的 console 结果为: A C B

但我预计要的 console 结果是: A B C


6 回复

为了更好地理解和解决你提到的 Node.js 程序中的异步处理问题,我们可以通过使用 Promise 或 async/await 来简化异步代码的编写,并确保代码按预期顺序执行。以下是改进后的代码示例,以及对问题的详细解释。

改进后的代码

const util = require('util');
const dbclient = require('./dbclient'); // 假设这是你的数据库客户端

// 将查询转换为 Promise 版本
const queryAsync = util.promisify(dbclient.query.bind(dbclient));

// 更新 SearchUser 函数
const SearchUser = async function(email) {
    console.log("A");

    try {
        const result = await queryAsync(`SELECT * FROM user WHERE email = "${email}"`);
        
        console.log("B");
        if (result.length > 0) {
            return true;
        } else {
            return false;
        }
    } catch (error) {
        console.error(error);
        return false;
    }

    console.log("C"); // 这行实际上不会被执行,因为函数在上面已经返回了
};

// 调用 SearchUser 函数
SearchUser('example@example.com').then(result => {
    console.log(result); // 输出查询结果
}).catch(error => {
    console.error(error); // 输出错误信息
});

解释

  1. 将查询转换为 Promise 版本:

    • 使用 util.promisify 将传统的回调风格的 dbclient.query 方法转换为返回 Promise 的版本,这样我们可以更方便地使用 async/await
  2. 更新 SearchUser 函数:

    • 使用 async 关键字定义 SearchUser 函数,这样可以使用 await 关键字来等待异步操作完成。
    • 在函数内部,我们首先打印 “A”,然后使用 await 等待查询结果。
    • 如果查询结果长度大于 0,则返回 true,否则返回 false
    • 使用 try/catch 块来捕获可能发生的错误,并返回 false
  3. 调用 SearchUser 函数:

    • 使用 .then().catch() 来处理异步函数的返回值和可能的错误。

通过这种方式,我们可以确保代码按预期顺序执行,并且避免了由于异步执行带来的不确定性。


的确是javascript擅自完成了这件事情,给片文章读一下:

http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/

补充了问题描述,请各位前辈多多拔刀相助。

一般解决方式为回调,还有可以用Promise之类的库。

兄弟你别整的这么复杂,先从最简单的查询做起,把所有的步骤都放在回调里面,肯定能行。

试试把try catch, render 放在函数里给callback。

在Node.js中,异步操作确实是一个常见的挑战。为了确保异步操作完成后才继续执行后续代码,可以使用回调函数、Promise或者async/await来管理异步流程。

在这个例子中,你可以通过使用回调函数来解决这个问题。你可以在回调函数内部处理返回值,并且在查询完成后再返回最终结果。以下是修改后的代码:

SearchUser = function (email, callback) {
    _SearchUser = function (email, callback) {
        dbclient.query("SELECT * FROM user WHERE email = \"" + email + "\"", function (err, isExist) {
            if (err) return callback(err);
            const exists = isExist.length > 0;
            callback(null, exists);
        });
    }

    console.log("A");

    _SearchUser(email, function (err, isExist) {
        console.log("B");

        console.log(isExist);

        // 返回最终结果
        callback(err, isExist);
    });

    console.log("C"); // 这行会在异步操作完成后执行
}

// 调用函数时传入回调
SearchUser("example@example.com", function (err, result) {
    if (err) throw err;
    console.log("Final Result:", result);
});

在这段代码中,_SearchUser 函数会在查询完成后调用回调函数,这样可以确保在执行 console.log("C") 之前已经获取到了查询结果。此外,通过将最终结果传递给外部的 callback,我们可以在最后得到正确的输出顺序和结果。

这种方法利用了回调函数来处理异步操作的完成情况,并确保了程序按预期顺序执行。

回到顶部