【问题标题】:Express Node.js Async promises alignment issueExpress Node.js Async 承诺对齐问题
【发布时间】:2020-04-03 17:09:38
【问题描述】:

我在一个 Web 应用程序中登录,它从 MongoDB 中读取数据并使用 lodash 将其排序到排序数组中。问题是我的console.log("sorted in /api/login:", sorted); 出于某种原因没有返回任何内容,这不会使console.log 输出yeet ...我该如何解决这个问题?我已经尝试过更多的等待,但这对我没有帮助。每个人都在谈论的这个承诺对齐是什么?我在网上找不到任何关于它的信息..

var express = require('express');
const app = express();
const User = require('./models/user.js');
var _ = require('lodash');
const sorted = [];
User.find({},{ firstname: 1, password: 1 }, async function(err, users) {
  const flattenUsers = _(users).map(({firstname, password}) => ([firstname, password])).flatten().value();
  console.log(flattenUsers);
  const sorted = await flattenUsers.reduce((a, e, i) => (i % 2 || a.push([]), a[a.length - 1].push(e), a), []);
  await console.log("sorted:", sorted);
});

app.post('/api/login', apiLimiter, async function (req, res){
  try  {
    console.log("sorted in /api/login:", sorted);
    console.log("Req firstname: ",req.body.firstname)
    const hashedPassword = await bcrypt.hash(req.body.password, 10);
    console.log("Hashed pw: ", hashedPassword);
    console.log(await bcrypt.compare('testtest',hashedPassword));
    // const user = { id: req.body.id, username: req.body.username, password: req.body.password };
    var user = new User({firstname: req.body.firstname, eMail: req.body.eMail, password: hashedPassword });
    sorted.forEach(async ([eMail, password]) => {
      await bcrypt.compare(password, users[eMail]).then((e, r) => {
        // r = true if hash = hashed pw
        console.log("Yeet");
      });
    });
    jwt2.sign({user}, 'secrethere', { expiresIn: '15min'}, (err, token) =>{
    res.json({
      token
    });
  });
  } catch (err) {
    res.status(500).send()
    console.log(err);
  }
});

我的 user.js:

const mongoose = require('mongoose');

const userSchema = mongoose.Schema({
  firstname: {
    type: String,
    required: true,
    unique: true
  },
  lastname: String,
  eMail: {
    type: String,
    required: true,
    unique: true
  },
  password: String,
  active: Boolean
});

module.exports = mongoose.model("User", userSchema);

更新

执行推荐答案时遇到的错误:

(node:17080) UnhandledPromiseRejectionWarning: ReferenceError: users 没有定义 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:252:38 在 Array.forEach () 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:17080) UnhandledPromiseRejectionWarning: Unhandled Promise 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝 ID:1)(节点:17080)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。在 未来,未处理的承诺拒绝将终止 具有非零退出代码的 Node.js 进程。 (节点:17080) UnhandledPromiseRejectionWarning:ReferenceError:未定义用户 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:252:38 在 Array.forEach () 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:17080) UnhandledPromiseRejectionWarning: Unhandled Promise 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝 ID:2)(节点:17080) UnhandledPromiseRejectionWarning:ReferenceError:未定义用户 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:252:38 在 Array.forEach () 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:17080) UnhandledPromiseRejectionWarning: Unhandled Promise 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝编号:3)

更新2

(node:11252) UnhandledPromiseRejectionWarning: 错误:数据和哈希参数 必需的 在 Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:209:17) 在 C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:29:12 在新的承诺 () 在 Object.module.exports.promise (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:20:12) 在 Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:205:25) 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 在 Array.forEach () 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:11252) UnhandledPromiseRejectionWarning: Unhandled Promise 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝 ID:1)(节点:11252)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。在 未来,未处理的承诺拒绝将终止 具有非零退出代码的 Node.js 进程。 (节点:11252) UnhandledPromiseRejectionWarning:错误:数据和哈希参数 必需的 在 Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:209:17) 在 C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:29:12 在新的承诺 () 在 Object.module.exports.promise (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:20:12) 在 Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:205:25) 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 在 Array.forEach () 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:11252) UnhandledPromiseRejectionWarning: Unhandled Promise 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝 ID:2)(节点:11252) UnhandledPromiseRejectionWarning:错误:数据和哈希参数 必需的 在 Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:209:17) 在 C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:29:12 在新的承诺 () 在 Object.module.exports.promise (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:20:12) 在 Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:205:25) 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 在 Array.forEach () 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:11252) UnhandledPromiseRejectionWarning: Unhandled Promise 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝编号:3)

更新 3

现在我收到这些错误:

(节点:14268)UnhandledPromiseRejectionWarning:错误:数据和哈希 需要参数 在 Object.compareSync (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:167:15) 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 在 Array.forEach () 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:14268) UnhandledPromiseRejectionWarning: Unhandled Promise 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝 ID:1)(节点:14268)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。在 未来,未处理的承诺拒绝将终止 具有非零退出代码的 Node.js 进程。 (节点:14268) UnhandledPromiseRejectionWarning:错误:数据和哈希参数 必填
在 Object.compareSync (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:167:15) 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 在 Array.forEach () 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:14268) UnhandledPromiseRejectionWarning: Unhandled Promise 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝 ID:2)(节点:14268) UnhandledPromiseRejectionWarning:错误:数据和哈希参数 必填
在 Object.compareSync (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:167:15) 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 在 Array.forEach () 在 C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:14268) UnhandledPromiseRejectionWarning: Unhandled Promise 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝编号:3)

【问题讨论】:

标签: javascript node.js express asynchronous mongoose


【解决方案1】:

您的问题是,当您在 express 中调用从 app.post('/api/login', apiLimiter, async function (req, res) 开始的函数的路由时。

所以这段代码永远不会被调用,只需将它放在函数内部(在 try 内部),一切都会正常工作

const sorted = [];
User.find({},{ firstname: 1, password: 1 }, async function(err, users) {
  const flattenUsers = _(users).map(({firstname, password}) => ([firstname, password])).flatten().value();
  console.log(flattenUsers);
  const sorted = await flattenUsers.reduce((a, e, i) => (i % 2 || a.push([]), a[a.length - 1].push(e), a), []);
  await console.log("sorted:", sorted);
});

更新,带函数的工作代码

var express = require('express');
const app = express();
const User = require('./models/user.js');
var _ = require('lodash');

async function getSorted(){
const sorted = [];
let users = await User.find({},{ firstname: 1, password: 1 });
  const flattenUsers = _(users).map(({firstname, password}) => ([firstname, password])).flatten().value();
  console.log(flattenUsers);
  const sorted = await flattenUsers.reduce((a, e, i) => (i % 2 || a.push([]), a[a.length - 1].push(e), a), []);
  console.log("sorted:", sorted);
return Promise.resolve([sorted,users])
}
app.post('/api/login', apiLimiter, async function (req, res){


  try  {
  let [sorted,users] = await getSorted();
    console.log("sorted in /api/login:", sorted);
    console.log("Req firstname: ",req.body.firstname)
    const hashedPassword = await bcrypt.hash(req.body.password, 10);
    console.log("Hashed pw: ", hashedPassword);
    console.log(await bcrypt.compare('testtest',hashedPassword));
    // const user = { id: req.body.id, username: req.body.username, password: req.body.password };
    var user = new User({firstname: req.body.firstname, eMail: req.body.eMail, password: hashedPassword });
    sorted.forEach(async ([eMail, password]) => {
      let result = bcrypt.compareSync(password, users[eMail]);
        // result = true if hash = hashed pw
        console.log("Yeet");
      });
    });
    jwt2.sign({user}, 'secrethere', { expiresIn: '15min'}, (err, token) =>{
    res.json({
      token
    });
  });
  } catch (err) {
    res.status(500).send()
    console.log(err);
  }
});

【讨论】:

  • Yeet 没有被打印出来:/ 并且 console.log("sorted in /api/login:", sorted); 仍然没有打印出来,可能是因为它超出了范围
  • 是的,现在的问题是因为 User.find 是承诺,所以您需要在 User.find 之前放置 await。
  • 您可以相应地编辑答案吗?它以您编写的方式向我抛出语法错误
  • @Munchkin 给你。
  • 将 const 更改为 var 现在我得到 UnhandledPromiseRejectionWarning: ReferenceError: users is not defined。更新了问题以包含完整的错误列表 P.S Yeet 也没有打印出来
猜你喜欢
  • 1970-01-01
  • 2017-05-15
  • 2017-01-13
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-05
相关资源
最近更新 更多