程式码的异步处理问题(已解决)
发布于 6个月前 作者 grass0916 530 次浏览

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

  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用得很熟了。

回到顶部