Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/440.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 TypeError:fn不是一个函数。module.exports中两个函数之间的差异_Javascript_Node.js - Fatal编程技术网

Javascript TypeError:fn不是一个函数。module.exports中两个函数之间的差异

Javascript TypeError:fn不是一个函数。module.exports中两个函数之间的差异,javascript,node.js,Javascript,Node.js,我正在尝试使用来自其他文件的函数来为路由创建asyn/await wrap。详情: 没有包装功能,一切正常 带时间的第二个func可以很好地使用类似的导出代码 当位于用户文件中时,wrap函数可以正常工作 问题:我遗漏了什么,以及如何从服务器文件中进行包装?提前谢谢你的提示 server.js let express = require('express'); let userRules = require('./private/routes/users'); app.use('/user',

我正在尝试使用来自其他文件的函数来为路由创建asyn/await wrap。详情:

没有包装功能,一切正常 带时间的第二个func可以很好地使用类似的导出代码 当位于用户文件中时,wrap函数可以正常工作 问题:我遗漏了什么,以及如何从服务器文件中进行包装?提前谢谢你的提示

server.js

let express = require('express');
let userRules = require('./private/routes/users');
app.use('/user', userRules);

function asyncWrap(fn) {
    return (req, res, next) => {
        fn(req, res, next).catch(next);
    };
}
function getCurrentTime() {
  return getDateTime(); //inner func
}
exports.getCurrentTime= getCurrentTime;
exports.asyncWrap = asyncWrap;
users.js

let express = require('express');
let router = express.Router();
const server = require('../../server');
router.post('/auth', server.asyncWrap(async (req, res, next) => { //this line throws error
    let user = await sql.getUserByEmail(req.body.email); 
    console.log(server.getCurrentTime()+req.body.email+" tried to auth"); // this works
    ...
}));
错误

module.exports它是从require调用返回的对象引用。 导出只是一个方便的变量,因此模块作者可以编写更少的代码 阅读文章。您将更好地了解如何创建自己的模块和使用node。

tl;博士

您有一个循环依赖性问题。server.js需要users.js,users.js同样需要server.js

按照nodeJS模块的工作方式,require调用加载文件,并在将其包装到函数中、传递模块、导出和一些其他参数后执行。即使在文件执行完成之前,模块名的模块/导出也已被缓存。执行后,文件中的代码将分配与module.exports或exports上的键关联的各种对象

现在,在您的例子中,执行从server.js开始,它需要第2行的users.js。该控件传递给users.js,第3行再次需要server.js。然后尝试调用server.asyncWrap,但该密钥将仅分配给server.js中第14行的导出。该文件的控件仍在第2行被阻止。因此,访问该键将返回未定义的非函数

有多种方法可以解决这个问题

您可以这样设计代码,即不存在循环依赖关系。也许可以将asyncWrap函数移动到其他地方的帮助文件中

第二,您可以将第二行和第三行从server.js移到文件的末尾,新文件应该如下所示:

let express = require('express');

function asyncWrap(fn) {
    return (req, res, next) => {
        fn(req, res, next).catch(next);
    };
}
function getCurrentTime() {
  return getDateTime(); //inner func
}
exports.getCurrentTime= getCurrentTime;
exports.asyncWrap = asyncWrap;

let userRules = require('./private/routes/users');
app.use('/user', userRules);`

虽然第二个选项也可以,但我强烈建议使用第一个选项。

我知道导出只是一条捷径。但是编写module.exports并不能解决使用函数的问题,不是吗?它应该可以解决您的问题。现在,asyncWrap函数不是由require“../../server”返回的;。尝试此模块。exports={getCurrentTime,asyncWrap}您可以在console.log中将您的服务器对象记录在users.js中。考虑到循环dpendencies,代码看起来很好,但是无法理解为什么其他函数在这些条件下工作。我认为问题在于从一开始就编译的中间件的使用。感谢您提供的选择。我同意第一个更好。
let express = require('express');

function asyncWrap(fn) {
    return (req, res, next) => {
        fn(req, res, next).catch(next);
    };
}
function getCurrentTime() {
  return getDateTime(); //inner func
}
exports.getCurrentTime= getCurrentTime;
exports.asyncWrap = asyncWrap;

let userRules = require('./private/routes/users');
app.use('/user', userRules);`