Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.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 如何解决NodeJS方法的优先级问题_Javascript_Node.js_Mongodb_Mongoose - Fatal编程技术网

Javascript 如何解决NodeJS方法的优先级问题

Javascript 如何解决NodeJS方法的优先级问题,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,在本例中,方法3首先起作用,我得到一个错误。其优先级必须与方法1、方法2和方法3类似。这些方法是承诺吗?而且承诺是异步的 我想检查新用户的用户名和电子邮件是否在使用中。如果用户名或电子邮件未被使用,请注册 我如何解决这个问题?我是新来的 module.exports.addUser = function(newUser, callback) { // method 1 User.countDocuments({username: newUser.username}).then(

在本例中,方法3首先起作用,我得到一个错误。其优先级必须与方法1、方法2和方法3类似。这些方法是承诺吗?而且承诺是异步的

我想检查新用户的用户名和电子邮件是否在使用中。如果用户名或电子邮件未被使用,请注册

我如何解决这个问题?我是新来的

module.exports.addUser = function(newUser, callback) {

    // method 1
    User.countDocuments({username: newUser.username}).then(count => {
        if(count > 0) {
            console.log("username in use");
            callback("username in use", null);
            return;
        }});

    // method 2
    User.countDocuments({email: newUser.email}).then(count => {
        if(count > 0) {
            console.log("email in use");
            callback("email in use", null);
            return;
        }});

    // method 3 , this method works first
    bcrypt.genSalt(10, (err, salt) => {
        console.log("salt here");
        bcrypt.hash(newUser.password, salt, (err, hash) => {
            if(err) throw err;
            newUser.password = hash;
            newUser.save(callback);
        });
    });
};
输出:

salt here
username in use
email in use

(node:7972) UnhandledPromiseRejectionWarning: Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:491:11)
    at ServerResponse.setHeader (_http_outgoing.js:498:3)
    at ServerResponse.header (C:\Users\cyclone\Desktop\my_auth\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (C:\Users\cyclone\Desktop\my_auth\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\Users\cyclone\Desktop\my_auth\node_modules\express\lib\response.js:267:15)
    at User.addUser (C:\Users\cyclone\Desktop\my_auth\routes\users.js:20:17)
    at User.countDocuments.then.count (C:\Users\cyclone\Desktop\my_auth\models\user.js:48:13)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:189:7)
(node:7972) 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:7972) [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.
events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:491:11)
    at ServerResponse.setHeader (_http_outgoing.js:498:3)
    at ServerResponse.header (C:\Users\cyclone\Desktop\my_auth\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (C:\Users\cyclone\Desktop\my_auth\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\Users\cyclone\Desktop\my_auth\node_modules\express\lib\response.js:267:15)
    at User.addUser (C:\Users\cyclone\Desktop\my_auth\routes\users.js:22:17)
    at C:\Users\cyclone\Desktop\my_auth\node_modules\mongoose\lib\model.js:4518:16
    at model.$__save.error (C:\Users\cyclone\Desktop\my_auth\node_modules\mongoose\lib\model.js:422:7)
    at C:\Users\cyclone\Desktop\my_auth\node_modules\kareem\index.js:315:21
    at next (C:\Users\cyclone\Desktop\my_auth\node_modules\kareem\index.js:209:27)
    at C:\Users\cyclone\Desktop\my_auth\node_modules\kareem\index.js:182:9
    at process.nextTick (C:\Users\cyclone\Desktop\my_auth\node_modules\kareem\index.js:499:38)
    at _combinedTickCallback (internal/process/next_tick.js:132:7)
    at process._tickCallback (internal/process/next_tick.js:181:9)
[nodemon] app crashed - waiting for file changes before starting...
这里放盐
正在使用的用户名
正在使用的电子邮件
(节点:7972)未处理的PromisejectionWarning:错误:发送标头后无法设置标头。
在validateHeader(_http_outgoing.js:491:11)
在ServerResponse.setHeader(_http_outgoing.js:498:3)
在ServerResponse.header(C:\Users\cyclone\Desktop\my\u auth\node\u modules\express\lib\response.js:767:10)
在ServerResponse.send(C:\Users\cyclone\Desktop\my\u auth\node\u modules\express\lib\response.js:170:12)
在ServerResponse.json(C:\Users\cyclone\Desktop\my\u auth\node\u modules\express\lib\response.js:267:15)
在User.addUser(C:\Users\cyclone\Desktop\my\u auth\routes\Users.js:20:17)
在User.countDocuments.then.count(C:\Users\cyclone\Desktop\my\u auth\models\User.js:48:13)
在
在进程中。_tick回调(内部/process/next_tick.js:189:7)
(节点:7972)未处理的PromisejectionWarning:未处理的承诺拒绝。此错误源于在没有catch块的异步函数中抛出,或者拒绝未使用.catch()处理的承诺。(拒绝id:1)
(节点:7972)[DEP0018]弃用警告:未处理的承诺拒绝已弃用。将来,承诺不处理的拒绝
将使用非零退出代码终止Node.js进程。
events.js:183
投掷者;//未处理的“错误”事件
^
错误:发送邮件后无法设置邮件头。
在validateHeader(_http_outgoing.js:491:11)
在ServerResponse.setHeader(_http_outgoing.js:498:3)
在ServerResponse.header(C:\Users\cyclone\Desktop\my\u auth\node\u modules\express\lib\response.js:767:10)
在ServerResponse.send(C:\Users\cyclone\Desktop\my\u auth\node\u modules\express\lib\response.js:170:12)
在ServerResponse.json(C:\Users\cyclone\Desktop\my\u auth\node\u modules\express\lib\response.js:267:15)
在User.addUser(C:\Users\cyclone\Desktop\my\u auth\routes\Users.js:22:17)
在C:\Users\cyclone\Desktop\my\u auth\node\u modules\mongoose\lib\model.js:4518:16
在model.$\uuuu save.error(C:\Users\cyclone\Desktop\my\u auth\node\u modules\mongoose\lib\model.js:422:7)
在C:\Users\cyclone\Desktop\my\u auth\node\u modules\kareem\index.js:315:21
下一步(C:\Users\cyclone\Desktop\my_auth\node\u modules\kareem\index.js:209:27)
在C:\Users\cyclone\Desktop\my\u auth\node\u modules\kareem\index.js:182:9
在process.nextTick(C:\Users\cyclone\Desktop\my\u auth\node\u modules\kareem\index.js:499:38)
at_combinedTickCallback(内部/流程/下一步勾选js:132:7)
在进程中。_tick回调(内部/process/next_tick.js:181:9)
[nodemon]应用程序崩溃-正在等待文件更改,然后再启动。。。
在countDocuments后面使用“then”这一事实确实表明它是一种承诺,因此是异步的

此时最简单的解决方案是将
addUser
函数定义为
async

module.exports.addUser = async function(newUser, callback) {

  // method 1
  const count1 = await User.countDocuments({
    username: newUser.username
  });

  if (count1 > 0) {
    console.log("username in use");
    callback("username in use", null);
    return;
  };

  // method 2
  const count2 = await User.countDocuments({
    email: newUser.email
  });

  if (count2 > 0) {
    console.log("email in use");
    callback("email in use", null);
    return;
  };

  // method 3 , this method works first
  bcrypt.genSalt(10, (err, salt) => {
    console.log("salt here");
    bcrypt.hash(newUser.password, salt, (err, hash) => {
      if (err) throw err;
      newUser.password = hash;
      newUser.save(callback);
    });
  });
};
然而,现在为addUser使用回调函数是毫无意义的,因为异步函数会自动返回一个承诺。我建议你这样做

module.exports.addUser = async function(newUser) {

  // method 1
  const count1 = await User.countDocuments({
    username: newUser.username
  });

  if (count1 > 0) {
    throw Error("username is in use");
  };

  // method 2
  const count2 = await User.countDocuments({
    email: newUser.email
  });

  if (count2 > 0) {
    throw Error("email in use");
  };

  let result = null;
  // method 3 , this method works first
  bcrypt.genSalt(10, (err, salt) => {
    console.log("salt here");
    bcrypt.hash(newUser.password, salt, (err, hash) => {
      if (err) throw err;
      newUser.password = hash;
      result = await newUser.save(callback);
    });
  });

  return result;

};
在使用中,它看起来像:

addUser(someUserObject).then(result=>console.log(result)).catch(error=>{
  //Example: username in use
  console.log(error.message)
});

它解决了我的问题。非常感谢你。但我有一个问题。在使用mongoose时,我必须使用异步方法吗?@ŞerefCanMuştu mongoose本质上是异步的,它们提供了一些同步方法变体,但并非所有方法都是如此。因此,一般来说,如果您使用mongoose,您将使用承诺/异步方法。你可以在任何地方使用承诺。。。但为了可读性,我建议使用async/await。您还可以使用co(),这也是mongoose文档中推荐的。。。虽然这是实现异步函数的另一种方式。