Как я могу получить массив данных из другого файла в Node.JS - PullRequest
0 голосов
/ 18 сентября 2018

Я создаю и использую Node-проект с MongoDB. У меня есть два файла, такие как 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. Почему?

1 Ответ

0 голосов
/ 18 сентября 2018

Как сказал @ 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 результат, но обратный вызов был вне этого обратного вызова и поэтому имеетбыл вызван до того, как этот обратный вызов сработал.Вот почему вы получаете 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 «Обещания» и async / await, но они выходят за рамки этого вопроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...