求教NodeJS的流程控制。也搜到很多解决方案,但是仍然不知道如何做。苦闷。

求教NodeJS的流程控制。也搜到很多解决方案,但是仍然不知道如何做。苦闷。

求学NodeJs的第一个星期,快被折磨死了,快放弃了,这玩意咋这么难学。Java的框架一两天就上手,这NodeJs尼玛是对自我的重新认识的利器啊。

为了避免大家常说的“回调陷阱”或“回调黑洞”。 我只是想实现根据第一步DB操作的结果来判断是不是要进行第二步DB操作,就这样,很简单。 问题来了, Q 、 async 等等一堆一下击败了我的弱脑。

能不能求大神给个痛快的,用什么实现都行。 如果用promise,那我访问数据库那一层要写成什么样子才能让上层.then。 如果用async,前一步的返回是后一步的输入,看不懂啊,怎么传给后一步的啊。

能不能给个代码示例啊! 泪水喷涌裸体奔跑中~~~~~。

下面是我查询数据库的代码片段: exports.checkUser = function(user, handler) { db.execQuery({ “sql”: “select * from user_info where user_name = ?”, “args”: [user.userName], “handler”: handler }); };


19 回复

新手上路不要用这堆东西 只会把自己搞晕,就用nodejs的回调好了 不是特别复杂的逻辑 ,回调没撒不好的,很多人还就喜欢回调。


当然可以!让我们通过一个简单的示例来解决这个问题,使用 async/awaitPromise 来处理流程控制。

使用 async/await 的示例

首先,我们可以通过将数据库查询包装在一个 Promise 中,然后使用 async/await 来简化异步流程控制。这样可以使代码更加清晰易读。

修改 checkUser 函数

我们将 checkUser 函数修改为返回一个 Promise

exports.checkUser = function(user) {
    return new Promise((resolve, reject) => {
        db.execQuery({
            "sql": "select * from user_info where user_name = ?",
            "args": [user.userName],
            "handler": (err, results) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(results);
                }
            }
        });
    });
};

使用 async/await 进行流程控制

接下来,我们可以使用 async/await 来编写更清晰的逻辑:

const checkUser = require('./path-to-your-module'); // 导入你的模块

async function main() {
    try {
        const user = { userName: 'testUser' };
        
        // 第一步:检查用户是否存在
        const userExists = await checkUser(user);
        
        if (userExists.length > 0) {
            console.log('用户已存在');
            
            // 如果用户已存在,执行第二步操作
            await performSecondStep();
        } else {
            console.log('用户不存在');
        }
    } catch (error) {
        console.error('发生错误:', error);
    }
}

function performSecondStep() {
    return new Promise((resolve, reject) => {
        // 模拟第二步DB操作
        setTimeout(() => {
            console.log('第二步操作完成');
            resolve();
        }, 1000);
    });
}

main();

解释

  1. checkUser 函数:现在返回一个 Promise,在成功时解析查询结果,在失败时拒绝并传递错误。
  2. main 函数:使用 async/await 编写,使得异步代码看起来像同步代码。
  3. performSecondStep 函数:模拟第二个数据库操作,这里使用 setTimeout 来模拟异步操作。

通过这种方式,你可以更清晰地控制异步流程,并且避免了传统的回调地狱问题。希望这能帮助你更好地理解 Node.js 中的流程控制。

好惨,帮顶一下

[@wuliao49](/user/wuliao49) 关键是逻辑混乱。如果要实现注册用户,那要先校验用户是否存在。 userModel.checkUser(user, function (result, error) { … …} userModel.insert(user, function(result, error) {… …} 这里插入操作可能在校验之前。 如果把insert写到check里面,也是可以,由于个人原因,这么写会让我烦躁的难以入睡。 a() { b() { c(){ 。。。。 就这样一直的美下去? } } }

[@CocaCola183](/user/CocaCola183) 不要看热闹,给指点指点。

如果js高级特性没理解,那么刚开始需要多踩几次坑,习惯了就懂了!

[@DevinXian](/user/DevinXian) 已经在坑里了。 能不能给指条明路呢?

[@wowxhycoming](/user/wowxhycoming) 我觉得这样求助会比较方便快捷,等代码的话估计可能行不大https://www.google.com.hk/#hl=zh-CN&q=site:cnodejs.org+%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6

[@CocaCola183](/user/CocaCola183) 打不开google的痛你可能无法理解。 [破涕为笑]

[@wowxhycoming](/user/wowxhycoming) 这个不错http://blog.fens.me/nodejs-async/

[@CocaCola183](/user/CocaCola183) 这位大拿请不要被我烦死。 这个我看了,可能是我理解的不深刻,这只是实现了一部分的控制,就是执行顺序。 但是并没有根据上一步的执行结果,来判断下面是不是需要执行。

首先,先不说流程控制,按照node的理念,insert是要写到check里面的。 如果简单的2,3层回调都不能接受的话,说明你要么太执念,要么完全不适应异步,趁早放弃。

其次 node里面又不是完全异步,大部分异步都是和IO相关的。 你这种简单的业务场景,撑死了就3成回调,我觉得完全可以接受。 离我们通常说的“回调地狱”差了十万八千里,

如果你接受,而且觉得自然的话,那么可以往下学了。 你这个等你实现很复杂的逻辑的时候,你就发现异步这种方式有缺陷。 需要采取流程控制来解决大规模回调。等你到这步,估计你已经知道怎么做了。 哪些所谓的Q 、 async等等,无非就是语法糖而已。你看哪个爽就哪个 你用哪个 或者自己写一个,或者采取别的方式 ,按照你习惯的来,甚至你可以直接用node原生的eventemit。 无所谓,没有高下之分。

而且你所谓的 烦躁的难以入睡 让我很奇怪。 web开发做过没?AJAX用过没?没用过的话 用过baidu地图或者google地图没? 有哪个异步ajax不是回调? 那你如果做web的话,那是不是天天难以入眠?

…回调说白了是换种模样的函数嵌套而已,有什么难以入睡的。如楼上大神言,不能接受回调,还是远离Node为好…照猫画虎,先用吧,用不了几天你就行了!

[@wowxhycoming](/user/wowxhycoming) async是可以根据上一部的结果来判断下一步是不是需要执行的 屏幕快照 2015-01-09 下午3.48.06.png(ps:我也是水货,刚开始学node,加油吧)

[@wuliao49](/user/wuliao49) 你好,想找人外包开发一个简单的静态网站,请问是否有朋友推荐?谢谢

[@DevinXian](/user/DevinXian) 你好,想找人外包开发一个简单的静态网站,请问是否有朋友推荐?谢谢

静态网站还来找开发?来错地方了

在Node.js中,流程控制是非常重要的一部分,特别是在处理异步操作时。常见的方法包括回调函数、Promise以及async/await。你提到的问题可以通过这些方法解决。下面是针对你问题的几个解决方案,以及一些示例代码。

使用Promise

如果你选择使用Promise,你需要修改你的数据库查询函数,使其返回一个Promise对象,这样你就可以使用.then来链式调用。

function checkUser(user) {
    return new Promise((resolve, reject) => {
        db.execQuery({
            "sql": "select * from user_info where user_name = ?",
            "args": [user.userName],
            "handler": (err, results) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(results);
                }
            }
        });
    });
}

// 使用示例
checkUser({ userName: 'test' })
    .then(results => {
        if (results.length > 0) {
            // 进行下一步操作
            return nextStep();
        }
    })
    .catch(err => console.error(err));

使用async/await

如果你更喜欢同步风格的代码,可以使用async/await。这种方式更加直观,也避免了回调地狱。

async function checkUserAndNext(user) {
    try {
        const results = await checkUser(user);
        if (results.length > 0) {
            // 进行下一步操作
            await nextStep();
        }
    } catch (err) {
        console.error(err);
    }
}

// 使用示例
checkUserAndNext({ userName: 'test' });

总结

无论是Promise还是async/await,它们都能有效地帮助你处理异步流程控制。推荐使用async/await,因为它使代码更加清晰易读。你可以根据自己的需求选择合适的方法。希望这能帮到你!

回到顶部