头疼的回调,请问我怎么等这个方法回调执行完再返回呢 Nodejs

头疼的回调,请问我怎么等这个方法回调执行完再返回呢 Nodejs

function getRandomName(namesList) { var realname = “”; client.get(‘userlist’, function (error, res) { var list = JSON.parse(res); var pos = Math.round(Math.random() * (list.length - 1)); var oo = list[pos]; realname = “[” + oo.user_code + “]” + oo.real_name; console.log(‘realname–’ + realname); }); return realname; };

我这个是从REDIS缓存中随机获取一个用户名字,这东西搞了我半天啦,都不知道怎么弄,真是头疼,不知道你们是怎么处理这样的问题的?


5 回复

function getRandomName(namesList, callback) { var realname = “”; client.get(‘userlist’, function (error, res) { var list = JSON.parse(res); var pos = Math.round(Math.random() * (list.length - 1)); var oo = list[pos]; realname = “[” + oo.user_code + “]” + oo.real_name; return callback(realname); }); };


在Node.js中,异步操作是一个常见的挑战,特别是当你需要等待某个操作完成后再进行下一步操作时。你当前的方法使用了回调函数,但这种方法容易导致“回调地狱”(callback hell),使得代码难以阅读和维护。更好的解决方法是使用Promise或者async/await语法来处理异步操作。

示例代码

首先,让我们重构你的getRandomName函数,使其返回一个Promise,并使用async/await来处理异步操作:

const client = require('redis').createClient(); // 假设你已经设置了Redis客户端

function getRandomName(namesList) {
    return new Promise((resolve, reject) => {
        client.get('userlist', function (error, res) {
            if (error) {
                reject(error);
            } else {
                try {
                    var list = JSON.parse(res);
                    var pos = Math.floor(Math.random() * list.length); // 使用Math.floor代替Math.round,避免越界
                    var oo = list[pos];
                    var realname = `[${oo.user_code}]${oo.real_name}`;
                    console.log('realname--' + realname);
                    resolve(realname);
                } catch (e) {
                    reject(e);
                }
            }
        });
    });
}

// 使用async/await来调用getRandomName
async function useRandomName() {
    try {
        const realname = await getRandomName();
        console.log('最终结果:', realname);
    } catch (error) {
        console.error('获取名字时出错:', error);
    }
}

useRandomName();

解释

  1. Promise:我们创建了一个新的Promise对象,当Redis操作成功时,通过resolve(realname)来传递结果;如果发生错误,则通过reject(error)来抛出错误。

  2. async/await:通过使用async关键字定义useRandomName函数,并在其中使用await关键字来等待getRandomName()函数的结果。这样可以确保在获取到Redis数据之前不会继续执行后续代码。

  3. 错误处理:使用try...catch结构来捕获可能发生的任何错误,包括JSON解析错误或Redis请求错误。

这种方式不仅使代码更加清晰易读,也更容易管理复杂的异步逻辑。

回调里面又肯定了个回调啊

return 是没有用的。直接嵌套写就好了。

在你的代码中,getRandomName 函数在 client.get('userlist', ...) 回调内部才设置 realname 的值。然而,这个函数在回调之前就返回了,因此 realname 还未被赋值。

为了解决这个问题,你可以使用回调函数来确保在返回结果之前完成异步操作。另外,如果你熟悉 ES6 或更高版本,也可以考虑使用 Promise 或 async/await 来简化代码逻辑。

使用回调函数的例子:

function getRandomName(namesList, callback) {
    client.get('userlist', function (error, res) {
        if (error) return callback(error);

        var list = JSON.parse(res);
        var pos = Math.round(Math.random() * (list.length - 1));
        var oo = list[pos];
        var realname = "[" + oo.user_code + "]" + oo.real_name;

        console.log('realname--' + realname);
        callback(null, realname); // 在回调中传递结果
    });
}

// 调用方式
getRandomName([], function (err, name) {
    if (err) return console.error(err);
    console.log(name);
});

使用 Promise 的例子:

function getRandomName(namesList) {
    return new Promise((resolve, reject) => {
        client.get('userlist', function (error, res) {
            if (error) return reject(error);

            var list = JSON.parse(res);
            var pos = Math.round(Math.random() * (list.length - 1));
            var oo = list[pos];
            var realname = "[" + oo.user_code + "]" + oo.real_name;

            console.log('realname--' + realname);
            resolve(realname);
        });
    });
}

// 调用方式
getRandomName([])
    .then(name => console.log(name))
    .catch(error => console.error(error));

使用 async/await 的例子:

async function getRandomName(namesList) {
    const { res } = await new Promise((resolve, reject) => {
        client.get('userlist', function (error, res) {
            if (error) return reject(error);
            resolve({ res });
        });
    });

    var list = JSON.parse(res);
    var pos = Math.round(Math.random() * (list.length - 1));
    var oo = list[pos];
    var realname = "[" + oo.user_code + "]" + oo.real_name;

    console.log('realname--' + realname);
    return realname;
}

// 调用方式
(async () => {
    try {
        const name = await getRandomName([]);
        console.log(name);
    } catch (error) {
        console.error(error);
    }
})();

通过这些方法,你可以确保在异步操作完成之后再返回或处理结果。

回到顶部