Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/462.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 错误:未处理的PromisejectionWarning:未处理的承诺拒绝_Javascript_Node.js_Express_Ecmascript 6_Es6 Promise - Fatal编程技术网

Javascript 错误:未处理的PromisejectionWarning:未处理的承诺拒绝

Javascript 错误:未处理的PromisejectionWarning:未处理的承诺拒绝,javascript,node.js,express,ecmascript-6,es6-promise,Javascript,Node.js,Express,Ecmascript 6,Es6 Promise,我正在使用nodejs、express和argon2。我遇到了这个错误,我不知道为什么。我没有任何回调,所以我不明白为什么会出现这个错误。这是我的密码: const express = require('express'); const app = express(); const port = 8080; const argon2 = require("argon2themax"); app.use(express.json()); // for parsing application/js

我正在使用nodejs、express和argon2。我遇到了这个错误,我不知道为什么。我没有任何回调,所以我不明白为什么会出现这个错误。这是我的密码:

const express = require('express');
const app = express();
const port = 8080;
const argon2 = require("argon2themax");

app.use(express.json()); // for parsing application/json
app.use(express.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded

// dumby
global.user = [{username:"u1", password:"hidden", email:"email@gmail.com"}];

// signin routes
app.post('/signup', function (req, res) {

  //console.log(req.body);

  // validate the json
  if(req.body.username === undefined || req.body.password === undefined) {
    res.status(500);
    res.render('error', { error: err });
  } else {
    try {

      // let argon2 generate our salt
      argon2.generateSalt()
      .then(function(salt) {

          // Hashing happens in an asynchronous event using libuv so your system can
          // still process other IO items in the Node.JS queue, such as web requests.
          return argon2.hash(req.body.password, salt, maxOpts);

      }).then(function(hash) {

          // This hash is what you should store in your database. Treat it as an opaque string.
          global.user.push({username:req.body.username, password:hash});

          // Verifying the hash against your user's password is simple.
          res.json(true);
      })
    } catch(error) {
      console.log("Unexpected error: " + error);
      //res.status(500);
      //res.render('error', { error: err });
    }
  }
})

app.post('/signin', function (req, res) {

  var success = false;

  global.user.forEach(function(item, index, array) {
    if(item.username == req.body.username) {
      try {
        argon2.verify(item.password, req.body.password).then(function(match) {
              if(match) {
                console.log("pword match");
                res.json(true);
              } else {
                res.json(false);
              }
              console.log("done");
          });
      } catch(err) {
        console.log(err);
      }
    } else {
      console.log("no uname");
      res.json(false);
    }
  });

})
只有当我在/signin路由之前点击我的/signup路由时,我的服务器才会抛出此错误。我相信这是一个异步问题,但我不知道如何解决它。完整的错误消息如下:

(node:21623) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)
    at ServerResponse.header (/Users/[redacted]/Public/Docs/[redacted]/node_modules/express/lib/response.js:775:10)
    at ServerResponse.send (/Users/[redacted]/Public/Docs/[redacted]/node_modules/express/lib/response.js:174:12)
    at ServerResponse.json (/Users/[redacted]/Public/Docs/[redacted]/node_modules/express/lib/response.js:271:15)
    at /Users/[redacted]/Public/Docs/[redacted]/server.js:106:17
(node:21623) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:21623) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

对于这两种方法,这不是为承诺链实现
catch
的正确方法:

try {

      // let argon2 generate our salt
      argon2.generateSalt()
      .then(function(salt) {

          // Hashing happens in an asynchronous event using libuv so your system can
          // still process other IO items in the Node.JS queue, such as web requests.
          return argon2.hash(req.body.password, salt, maxOpts);

      }).then(function(hash) {

          // This hash is what you should store in your database. Treat it as an opaque string.
          global.user.push({username:req.body.username, password:hash});

          // Verifying the hash against your user's password is simple.
          res.json(true);
      })
    } catch(error) {
      console.log("Unexpected error: " + error);
      //res.status(500);
      //res.render('error', { error: err });
    }
相反,您应该做如下操作:

  // let argon2 generate our salt
  argon2.generateSalt()
  .then(function(salt) {

      // Hashing happens in an asynchronous event using libuv so your system can
      // still process other IO items in the Node.JS queue, such as web requests.
      return argon2.hash(req.body.password, salt, maxOpts);

  }).then(function(hash) {

      // This hash is what you should store in your database. Treat it as an opaque string.
      global.user.push({username:req.body.username, password:hash});

      // Verifying the hash against your user's password is simple.
      res.json(true);
  }).catch(error => {
       console.log("Unexpected error: " + error);
  });

这通常意味着您在同一代码路径中调用了两次
res.status
。我根本不调用res.status。我猜这是express中调用res.status的东西,但我不确定在放入调试语句之后,我发现这是一个异步问题。线程退出/signin处理程序,并在argon2.verify()上等待完成,然后返回到该分支。我该如何解决这个问题?可能是@VikashSingh的复制品最初我也这么认为,但后来发现这只是症状。下面描述了真正的问题。这并没有解决问题,但是.catch()之间的区别是什么试着抓住?我只是想了想,我意识到这可能会解决问题,但我解决了另一个问题way@JustinCase关于您的第一条注释:用try/catch包围代码不会有帮助,因为此代码返回未实现的承诺,所以在执行退出try子句之前不会“抛出”任何内容。