我正在创建与MongoDB一起使用的Node项目。我有两个文件,例如change_language.js
和admin_event.js
。我在change_language.js
文件中创建了一个函数,并从其他文件(admin_event.js
)中调用了该函数。
change_language.js
const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
var assert = require('assert');
const request = require("request");
const Entity_option = require("../models/entity_option");
var ObjectId = require('mongodb').ObjectID;
require("../routes/admin_event");
function change_language(language_id)
{
let myRes=[];
Entity_option.aggregate([
{$match:{"language_id":ObjectId(language_id)}}
], function (err, result)
{
if (err)
{
myRes=err;
}
else
{
myRes= result;
}
console.log(myRes); // Print 1
})
return myRes;
}
module.exports.change_language = change_language;
admin_event.js
const express = require("express");
const router = express.Router();
const Event = require("../models/event");
const myLan=require("../setting/change_language").change_language;
var ObjectId = require('mongodb').ObjectID;
let language_id="5b9f5b324ae85e12a869187c";
let x = myLan(language_id);
console.log(x); // Print 2
module.exports = router;
该功能按预期工作。 console.log(myRes)
(打印1行)在命令提示符下显示输出。但是,当我从另一个文件(console.log(x)
)调用该函数时,显示的是undefined
。为什么?
答案 0 :(得分:1)
正如@ ponury-kostek所说,这实际上是Node.js新手常见问题的重复。
函数change_language
是一个异步函数,但是您要在该异步任务有机会完成之前返回一个值。
什么是异步功能?传统上,Nodejs使用的回调函数已经在这里进行了探讨,只是有些误解。
Entity_option.aggregate([{
$match:{"language_id":ObjectId(language_id)}
}], function (err, result) {
if (err) {
myRes=err;
}
else {
myRes= result;
}
console.log(myRes); // => 1
})
在这里,我们正在进行一个函数调用,该函数返回一个回调。在主函数(Entity_option.aggregate)完成之前,不会调用此回调函数(带有错误和结果的函数)。这可以在任何时间进行,因此您不能依靠立即从包装器函数返回任何值。因此,我们需要使用一些嵌套的回调使所有代码异步。
在现有代码中,您尝试将myRes分配给result,但是return调用不在此回调之外,因此已在触发该回调之前被调用。这就是为什么您得到undefined
的原因。基本上,您不是在等待异步任务完成。这就像将面包放到烤面包机中,将其推下,但立即尝试将烤面包归还。当然还没有准备好!
以下是代码外观的示例。
change_language.js
// All your various requires etc...
function change_language(language_id, callback) {
let myRes=[];
Entity_option.aggregate([{
$match:{"language_id":ObjectId(language_id)}
}], function (err, result) {
if (err) {
myRes=err;
} else {
myRes= result;
}
callback(err, result);
});
}
module.exports.change_language = change_language;
admin_event.js
const express = require("express");
const router = express.Router();
const Event = require("../models/event");
const myLan=require("../setting/change_language").change_language;
var ObjectId = require('mongodb').ObjectID;
let language_id="5b9f5b324ae85e12a869187c";
// Supply a callback as this is an async call
// the callback will be triggered once the async
// process (such as talking to a database) has finished
// or errored.
myLang(language_id, function(err, result) {
let x = result;
console.log(result);
});
module.exports = router;
如果执行此操作,您将很快看到回调样式代码的一些问题。因此,我建议您着眼于JavaScript“ Promises”和async / await,但这不在此问题的范围内。