我收到TypeError [ERR_INVALID_CALLBACK]:回调必须是一个函数

时间:2018-12-02 18:14:58

标签: node.js

我使用express-formidable来处理表单的上载。表单的常规字段已安装到req.fields

由表单上载的文件被挂载到req.files,并且文件存储在public/img目录中。然后验证参数。

通过验证后,用户信息将插入到MongoDB中。如果成功,它将跳转到主页并显示“注册成功”的通知。如果失败(如果用户名被占用),它将跳回到注册页面并显示“用户名已被占用”通知。

  

TypeError [ERR_INVALID_CALLBACK]:回调必须是一个函数

const fs = require('fs')
const path = require('path')
const sha1 = require('sha1')
const express = require('express')
const router = express.Router()

const UserModel = require('../models/users')
const checkNotLogin = require('../middlewares/check').checkNotLogin

//Get /register The Page to Create account
router.get('/', checkNotLogin, function (req, res, next){
    res.render('register')
})

router.post('/', checkNotLogin, function(req, res, next){
     const name = req.fields.name
     const gender = req.fields.gender
     const emailaddress = req.fields.emailaddress
     const bio = req.fields.bio
     const avatar = req.files.avatar.path.split(path.sep).pop()
     let password = req.fields.password
     const repassword = req.fields.repassword

     try {
         if (!(name.length >= 1 && name.length <= 10)) {
           throw new Error('Username can not be longer than 10 characters')
         }
         if (['m', 'f', 'x'].indexOf(gender) === -1) {
           throw new Error('Gender only can be m、f or x')
         }
         if(!emailaddress.endsWith('.co.uk')){
             throw new Error('Email Address should be an academic address')
         }
         if (!(bio.length >= 1 && bio.length <= 30)) {
           throw new Error('Please organise your personal description with in 30 characters')
         }
         if (!req.files.avatar.name) {
           throw new Error('Please choose your avator')
         }
         if (password.length < 6) {
           throw new Error('Password should be longer than 6 characters')
         }
         if (password !== repassword) {
           throw new Error('Re-enter the password you set')
         }
       } catch (e) {
         // register fail, delete the avator
         fs.unlink(req.files.avatar.path)
         req.flash('error', e.message)
         return res.redirect('/register')
       }

       // text password encryption
       password = sha1(password)

       // information wait to be enter into database
       let user = {
         name: name,
         password: password,
         emailaddress:emailaddress,
         gender: gender,
         bio: bio,
         avatar: avatar
       }
       // enter user information into database
       UserModel.create(user)
         .then( function (result) {
           user = result.ops[0]
           // delete password,store user information into session
           delete user.password
           req.session.user = user
           //Write into flash
            req.flash('success', 'Account Successfully created')
           // Jump to the home
           res.redirect('/posts')
          })
         .catch(function (e) {
           // Account create failure, delete avator
            fs.unlink(req.files.avatar.path)
           // if username already been use return to register page
           if (e.message.match('duplicate key')) {
             req.flash('error', 'username already be taken')
             return res.redirect('/register')
           }
          next(e)
         })
      })

     module.exports = router

我不确定哪里出了问题 我想已经有功能了 任何帮助将不胜感激

这是完整的错误消息:

 TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
 at makeCallback (fs.js:137:11)
 at Object.unlink (fs.js:936:14)
 at D:\tttt\CVsWeb\routes\register.js:48:1 express\lib\router\layer.js:95:5)
 at Layer.handle [as handle_request] (D:\tttt\CVsWeb\node_modules\137:13 express\lib\router\layer.js:95:5)
 at next        (D:\tttt\CVsWeb\node_modules\express\lib\router\route.js:express\lib\router\layer.js:95:5)137:13)                                                              137:13)
 at checkNotLogin (D:\tttt\CVsWeb\middlewares\check.js:14:9)      \route.js:112:3)
 at Layer.handle [as handle_request(D:\tttt\CVsWeb\node_modules\express\lib\router\layer.js:95:5)express\lib\router\layer.js:95:5)
at next (D:\tttt\CVsWeb\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (D:\tttt\CVsWeb\node_modules\express\lib\router\route.js:112:3)
  at Layer.handle [as handle_request] (D:\tttt\CVsWeb\node_modules\express\lib\router\layer.js:95:5)

1 个答案:

答案 0 :(得分:1)

fs.unlink是异步的,需要将回调函数作为第二个参数传递。

尝试使用fs.unlinkSync(req.files.avatar.path)或将函数作为第二个参数插入unlink fs.unlink(req.files.avatar.path, function(){console.log('Deleted avatar')})

router.post('/', checkNotLogin, function(req, res, next) {
  const name = req.fields.name
  const gender = req.fields.gender
  const emailaddress = req.fields.emailaddress
  const bio = req.fields.bio
  const avatar = req.files.avatar.path.split(path.sep).pop()
  let password = req.fields.password
  const repassword = req.fields.repassword

  try {
    if (!(name.length >= 1 && name.length <= 10)) {
      throw new Error('Username can not be longer than 10 characters')
    }
    if (['m', 'f', 'x'].indexOf(gender) === -1) {
      throw new Error('Gender only can be m、f or x')
    }
    if (!emailaddress.endsWith('.co.uk')) {
      throw new Error('Email Address should be an academic address')
    }
    if (!(bio.length >= 1 && bio.length <= 30)) {
      throw new Error('Please organise your personal description with in 30 characters')
    }
    if (!req.files.avatar.name) {
      throw new Error('Please choose your avator')
    }
    if (password.length < 6) {
      throw new Error('Password should be longer than 6 characters')
    }
    if (password !== repassword) {
      throw new Error('Re-enter the password you set')
    }
  } catch (e) {
    // register fail, delete the avator
    fs.unlinkSync(req.files.avatar.path) //Try this!
    req.flash('error', e.message)
    return res.redirect('/register')
  }

  // text password encryption
  password = sha1(password)

  // information wait to be enter into database
  let user = {
    name: name,
    password: password,
    emailaddress: emailaddress,
    gender: gender,
    bio: bio,
    avatar: avatar
  }
  // enter user information into database
  UserModel.create(user)
    .then(function(result) {
      user = result.ops[0]
      // delete password,store user information into session
      delete user.password
      req.session.user = user
      //Write into flash
      req.flash('success', 'Account Successfully created')
      // Jump to the home
      res.redirect('/posts')
    })
    .catch(function(e) {
      // Account create failure, delete avator
      fs.unlinkSync(req.files.avatar.path) //Also this one
      // if username already been use return to register page
      if (e.message.match('duplicate key')) {
        req.flash('error', 'username already be taken')
        return res.redirect('/register')
      }
      next(e)
    })
})