【问题标题】:Requiring modules from inside imported classes从导入的类中需要模块
【发布时间】:2018-11-09 15:15:31
【问题描述】:

假设我有以下样板快递应用程序:

const express = require('express');
const app = express();
const Person = require('./controllers/person.js');


app.get('/', (req, res) => {
})

app.post('/', (req, res) => {
    var person = new Person('Bob', 'Smith');
    res.send(person.sayHello());
});

app.listen(port, () => {
    console.log('Example app listening on port ' + 3000);
})

我的 person.js 文件如下所示:

module.exports = class Person {

   constructor(first, last) {
       this.first = first;
       this.last = last;
       this.sayHello();
   }


   sayHello() {
       return ('Hi, my name is ' + this.first + ' ' + this.last)
   }

}

现在一切正常,但是当我想导入将在 person 类上工作的模块时,事情就中断了。

例如,如果我将Person.sayHello() 更改为:

async sayHello() {
       var axios = require('axios')
       var response = await axios.get('https://jsonplaceholder.typicode.com/todos/1')
       return response.title
   } 

整个项目拒绝服务请求。我已经解决了问题是我需要新模块的那一行,但我想不出另一种方法来只为该类需要该模块?

此外,这里的异步不是问题,如果我将 sayHello() 函数更改为:

sayHello() {
       var axios = require('axios')
       return 'This line is never returned';
}

服务器仍然出错,GET 请求给了我一个ERR_CONNECTION_REFUSED

【问题讨论】:

  • 嗯,我的 asyncs 有点缺少 atm,但也许:var person = new Person('Bob', 'Smith'); var title = await person.sayHello(); res.send(title); 你会立即发送 sayHello 的响应,而无需等待 axios 请求解决。
  • 您将person.sayHello() 的结果传递给res.send,但是,因为sayHello 是一个异步函数,您需要thenawait 才能得到结果。
  • “拒绝服务请求”是什么意思?你有错误吗?超时?究竟是什么?
  • 尝试在 express 应用程序之外加载 person 类,例如制作一个简单的测试文件,加载 person 类并打招呼(只需使用 node 运行它),你会得到什么?
  • @NikosM。一个 POST 到 / 返回 503。

标签: javascript node.js express ecmascript-6


【解决方案1】:

您将person.sayHello() 的结果传递给res.send,但是,因为sayHello 是一个异步函数,您需要thenawait 来获得Promise 的结果。这些函数也在你的 Person 构造函数中调用,而不执行 Promise。我认为它是多余的,因为您在启动一个人后在您的快速应用程序中调用该函数。

app.post('/', async (req, res) => {
  const person = new Person('Bob', 'Smith');

  try {
    res.send(await person.sayHello());
  } catch(error) {
    res.send(error.message || `${error}`);
  }
});

你还会发现来自axios的响应没有title属性,你需要通过response.data.title来访问。

module.exports = class Person {
  constructor(first, last) {
    this.first = first;
    this.last = last;
  }

  async sayHello() {
    const axios = require('axios');
    const response = await axios.get(
      'https://jsonplaceholder.typicode.com/todos/1'
    );

    return response.data.title;
  }
}

不确定您是否已从问题中删除了快速应用程序中获取请求的实现,或者您是否实际上还没有。如果是这种情况,它将对 / 的 GET 请求超时。

const express = require('express');
const app = express();
const Person = require('./controllers/person.js');

app.get('/', (req, res) => {
  res.send('Hello, World!');
})

app.post('/', async (req, res) => {
  const person = new Person('Bob', 'Smith');
  res.send(await person.sayHello());
});

app.listen(3000, () => {
  console.log('Example app listening on port ' + 3000);
})

无论如何,使用前面的两个代码块,我能够成功地在 sayHello 函数中要求 axios 并返回响应数据的标题。但是,我无法重现您所描述的问题,除了由于空路由导致的超时。

【讨论】:

  • 我应该更具体一点,我也试过这个,但我的问题是,当我调用这个函数时,整个快速服务器关闭并给我一个ERR_CONNECTION_REFUSED,异步部分不是与此特定问题相关的是,在导致错误的函数内部动态需要节点的行。
  • 你要求模块在函数内部是必需的吗?当你在函数中不需要它时它是否有效。
  • 好吧,我把它放在问题中是因为它似乎是最有可能去的地方,但是当我将它包含在子类中的任何地方时,它会失败。
  • 如果你在类外声明并要求 axios,在文件顶部module.exports上方会发生什么?
  • 那么我服务器的响应是空的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多