如何从Node.JS中的另一个文件获取数组数据

时间:2018-09-18 08:06:03

标签: node.js express

我正在创建与MongoDB一起使用的Node项目。我有两个文件,例如change_language.jsadmin_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。为什么?

1 个答案:

答案 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,但这不在此问题的范围内。