node.js - 为什么我的异步等待无法正常工作

标签 node.js express node-modules

我正在使用express js开发api,在我的api调用中我调用了2个函数,第一个是login(),其他函数是get_organizations(),但是get_organization() 在没有完成 login() 函数的情况下调用,我使用了 async wait 但它无法正常工作,有人可以帮我解决这个问题吗?我已在此处添加了整个代码,

router.get('/', async (req, res) => {
    let token = await login();
    await get_organizations(token);
});

const get_organizations = async function (api_token) {
    try {
        console.log('Get List Of Organizations');
        console.log('Verifying token');
        let verify_token_data = await jwt.verify(api_token, config['token-secret']);
        console.log(verify_token_data);
        return false;      
    } catch (error) {
        console.log(error);
    }
}

const login = async function () {
    try {
        console.log('Login process started');
        const newToken = await jwt.sign({login:'login'},config['token-secret'],{ expiresIn: config['token-expires']});
        let username = 'root_admin'
        let password = 'Admin123';
        let token = String(cryptojs.lib.WordArray.random(20));
        console.log("token : "+token);
        await connection.query('SELECT * FROM users where username = ?  ',[username], async function(err, rows) {
            if (err) {
                console.log("Looged out failed");
            } else {
                const user = rows[0];
                console.log("psdsdsd");
                if(bcrypt.compareSync(password,user.passwordHash)) {
                    await connection.query('SELECT * FROM organizations where id = ?  ',[user.organizationId], async function(err, org_data) {
                        if (err) {
                            console.log("Looged out failed");
                        } else {
                            console.log("sdsd");
                            //console.log(org_data);
                            if(typeof org_data.name!='undefined') {
                                organization = org_data.name;
                            } else {
                                organization = 'VeriCurious';
                            }
                            //console.log(organization);
                            // create a token
                            const token = await jwt.sign({ id: user.id, username: user.username, organizationId: user.organizationId, organization: organization}, config['token-secret'], {
                                expiresIn: config['token-expires'] // expires in 30 minutes
                            }); 
                            console.log("Successfull loggedin");
                            console.log("New generated token : "+token);
                            return token;
                        }
                    });    
                }
            }    
        });

    } catch (error) {
        console.log(error);
    }
}

最佳答案

当您在调用函数时使用 await 时,您基本上是在等待该函数内部的 Promise 得到解析。调用的函数旨在返回该 promise

在您的代码中,login 函数确实调用 connection.query,但没有任何等待查询解析的 Promise。

为了让 await 真正等待 connection.query,您需要返回一个 Promise,该 Promise 会在用户最终登录时解析 - 即您拥有 token :

const login = async function () {
  try {
    console.log('Login process started');
    const newToken = await jwt.sign({login:'login'},config['token-secret'],{ expiresIn: config['token-expires']});
    let username = 'root_admin'
    let password = 'Admin123';
    let token = String(cryptojs.lib.WordArray.random(20));
    console.log("token : "+token);

    return new Promise(function(resolve, reject){

      connection.query('SELECT * FROM users where username = ?  ',[username], async function(err, rows) { // await won't do anything here,
      // you should only use await with functions that return promises.
        if (err) {
          console.log("Looged out failed");
          throw new Error(err);
        } else {
          const user = rows[0];
          console.log("psdsdsd");
          if(bcrypt.compareSync(password,user.passwordHash)) {
            await connection.query('SELECT * FROM organizations where id = ?  ',[user.organizationId], async function(err, org_data) {
              if (err) {
                console.log("Looged out failed");
                throw new Error(err);
              } else {
                console.log("sdsd");
                //console.log(org_data);
                if(typeof org_data.name!='undefined') {
                  organization = org_data.name;
                } else {
                  organization = 'VeriCurious';
                }
                //console.log(organization);
                // create a token
                const token = await jwt.sign({ id: user.id, username: user.username, organizationId: user.organizationId, organization: organization}, config['token-secret'], {
                  expiresIn: config['token-expires'] // expires in 30 minutes
                }); 
                console.log("Successfull loggedin");
                console.log("New generated token : "+token);
                resolve(token); // this signals the Promise to resolve.
                // return token;
              }
            });
          }
        }    
      });
    });
  } catch (error) {
      console.log(error);
  }
}

一些注意事项:

  1. Await 旨在与 Promise 配合使用。 JavaScript 中的异步函数,要么接受回调,要么返回 promise 。 connection.query 需要回调,因此 await 在那里没有用。
  2. 您用来与数据库对话的模块 -mongoose? - 很可能有一个 promise 的 API。检查一下,因为如果您愿意使用 async/await,最好直接使用 Promise,而不是将代码包装在新的 Promise 中。

例如,如果connection.query返回一个Promise,你可以这样做:

const login = async function () {
  // skipped a lot of code and logic since this is an example
    const rows = await connection.query('SELECT * FROM users where username = ?  ',[username]);
    const user = rows[0];
    const org_data = await  connection.query('SELECT * FROM organizations where id = ?  ',[user.organizationId]);
    const organization = org_data.name;

    return await jwt.sign({ id: user.id, username: user.username, organizationId: user.organizationId, organization: organization}, config['token-secret'], {
                expiresIn: config['token-expires'] // expires in 30 minutes
  });
}

处理错误非常简单。

  • 当您在 async 函数内的回调中遇到错误,并且返回一个新的 Promise 时(就像在我的示例中一样),我真的不知道是拒绝还是抛出错误更好。我认为两者都会做同样的事情,但我不确定。
  • 关于node.js - 为什么我的异步等待无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58264832/

    相关文章:

    node.js - 任何人都可以发布一个使用 node.js 查询 postgresql 数据库的 RXJS 示例吗?

    angularjs - Express Node 服务器中的 "SyntaxError: Unexpected token n"

    javascript - 错误 : Evaluation failed: ReferenceError: res is not defined

    asp.net - iisnode 401消息返回iis页面

    javascript - npm:在 linux ubuntu 中使用 npm 命令时出现找不到模块 semver 错误

    node.js - 错误: invalid_request getToken

    node.js - 使用异步和同步调用收集结果

    node.js - LTI 使用 Node.js 启动身份验证

    npm - 如何查看node_modules依赖树?

    javascript - 由于绑定(bind)安装,Dockerfile 和 docker-compose 找不到节点模块