程式码的异步处理问题(已解决)
发布于 10 年前 作者 grass0916 4029 次浏览 最后一次编辑是 8 年前

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

  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

10 回复

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

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

@alaaf 多谢前辈,同时我搭配了以下网页的说明更了解 node 的处理方式,但想了解我这种情况不晓得要如何等待接收函数 _SearchUser 的回传结果呢?

http://www.ruanyifeng.com/blog/2013/10/event_loop.html

@alaaf 基本上我对setTimeout的是熟悉的,但目前的情况下,我还是第一次遇到。

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

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

@coolicer

前辈你好,经过一番折腾后处理为以下,您看看

还是有一些问题无法克服(无奈)


app.post('/create_member_check', function(req, res) {
	var Authenticate = function () {
		SearchUser(req.body.email, function (isExist) { 
			if (isExist === true)
				throw 101;
			else if (req.body.email === undefined || req.body.email == "")
				throw 102;
			else if (req.body.password === undefined || req.body.password == "")
				throw 103;
			else if (isExist === undefined)
				throw 104;

			var user = {
				"email": req.body.email,
				"password": req.body.password
			};
			AddUser(user);
			// 这个 return 无效
			return user;
		});
	}

	try {
		var userInfo = Authenticate();
	}
	catch (err) {
		var userInfo;
		if (err == 101)
			userInfo = "[Error] This account already exists.";
		else if (err == 102)
			userInfo = "[Error] Please key in 'email'.";
		else if (err == 103)
			userInfo = "[Error] Please key in 'password'.";
		else if (err == 104)
			userInfo = "[Fatal Error] SearchUser return 'undefined'.";
	}

	res.render("login_system/create_member_check", {
		layout: false,
		pagename: "create",
		authenticate: userInfo
	});
});

SearchUser = function (email, callback) {
	dbclient.query("SELECT * FROM user WHERE email = \"" + email + "\"", function (err, results) {
		if (err || results.length <= 0)
			callback(false);
		else
			callback(true);
	});
}

@grass0916

你的return无效,会不会是Adduser里面有其他的影响了

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

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

@coolicer @alaaf 感谢各位,我跌跌撞撞几次后终于有结果了

app.post('/create_member_check', function (req, res) {
	var Authenticate = function (req, callback) {
		SearchUser(req.body.email, function (isExist) { 
			if (isExist === true)
				return callback(101);
			else if (req.body.email === undefined || req.body.email == "")
				return callback(102);
			else if (req.body.password === undefined || req.body.password == "")
				return callback(103);
			else if (isExist === undefined)
				return callback(104);

			var user = {
				"email": req.body.email,
				"password": req.body.password
			};
			AddUser(user);
			callback(null, user);
		});
	}

	Authenticate(req, function (err, user) {
		var userInfo;
		if (err == 101)
			userInfo = "[Error] This account already exists.";
		else if (err == 102)
			userInfo = "[Error] Please key in 'email'.";
		else if (err == 103)
			userInfo = "[Error] Please key in 'password'.";
		else if (err == 104)
			userInfo = "[Fatal Error] SearchUser return 'undefined'.";
		else
			userInfo = "[Success] Created the account.";

		res.render("login_system/create_member_check", {
			layout: false,
			pagename: "create",
			authenticate: userInfo
		});
	});
});

@grass0916 看来callback用得很熟了。

回到顶部