使用 Node.js 从其他文件调用方法

Calling methods from other files with Node.js

我没有要求从我的 ./db/index.js 到我的 server.js 文件的方法到数据库中的 select 数据并显示它。

/db/index.js是这样的:

'use strict';

const pgp = require('pg-promise')();
const pg = pgp(process.env.DATABASE_URL);

let select = () => {
    pg.any('SELECT username, status FROM status')
        .then(function(data){
            for (var item of data) {
                return item.username + "'s status is " + item.status;
            }
        })
        .catch(function(err) {
            return 'Error: ' + err.message || err;
        });
};

module.exports = () => {
    select
};

我想从另一个文件调用它:

'use strict';

const port = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const db = require('./db/');

app.use(bodyParser.urlencoded({extended: true}));

app.post('/logdash', function(req, res, next) {
    res.status(200).send(db.select());
});

app.listen(port, function() {
    console.log('Server is running on port', port);
});

我正在使用 Heroku,像这样,观察日志,终端和 Slack 都没有显示错误(这是一个斜杠命令)。我找不到有关如何正确分离功能的帮助。我如何调用此 select 方法以及来自不同文件的任何其他方法?

您的模块中的代码是异步的。您不能直接 return 一个值。相反,您应该 return 承诺,然后使用来自调用者的承诺来获取最终的异步值。

有关此一般概念的进一步讨论,请参阅此答案:

How do I return the response from an asynchronous call?

将您的代码更改为此(参见嵌入的评论):

'use strict';

const pgp = require('pg-promise')();
const pg = pgp(process.env.DATABASE_URL);

let select = () => {
    // return the promise here
    return pg.any('SELECT username, status FROM status')
        .then(function(data){
            return data.map(function(item) {
                return item.username + "'s status is " + item.status;
            });
        })
        .catch(function(err) {
            // to keep this an error, we have to rethrow the error, otherwise
            // the rejection is considered "handled" and is not an error
            throw 'Error: ' + err.message || err;
        });
};

// export the function
module.exports.select = select;

并这样称呼它:

'use strict';

const port = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const db = require('./db/');

app.use(bodyParser.urlencoded({extended: true}));

app.post('/logdash', function(req, res, next) {
    db.select().then(function(data) {
        res.status(200).json(data);
    }).catch(function(err) {
        // add some sort of error response here
        res.status(500).json(err);
    });
});

app.listen(port, function() {
    console.log('Server is running on port', port);
});

此处的更改摘要:

  1. select()、return的承诺
  2. select() 中的 .catch() 中,重新抛出错误以使其保持被拒绝的承诺。如果您为 .catch() 添加处理程序并且不重新抛出或 return 被拒绝的承诺,那么错误将得到处理并且承诺将得到解决。
  3. 您需要修复 for 循环。它不应该在没有条件检查的情况下在 for 循环中执行 return。该代码可能只是错误的(尽管我不确定您打算做什么)。
  4. 当您调用 db.select() 时,使用 .then() 处理程序获取最终解析值。
  5. db.select() 承诺添加错误处理程序。
  6. 更改导出,使 db.select() 成为您的函数。
  7. 修改了您在 for 循环中引用数据的方式,因此它实际上会获取所需的 属性。

您的代码中存在很多问题,其中一些已在@jfriend00 之前的回答中列出。

我只会补充一点,当方法成功时,您也不会 return 来自该方法的任何数据。

考虑到你在那里犯了多少错误,我不会重复它们,而是给你一个更正的代码示例。

数据库模块:

'use strict';

const pgp = require('pg-promise')();
const db = pgp(process.env.DATABASE_URL);

let select = (req, res, next) =>
    db.map('SELECT username, status FROM status', null, row=> {
        return row.username + "'s status is " + row.status;
    })
        .then(data=> {
            res.status(200).send(data);
        })
        .catch(err=> {
            res.status(500).send(err.message || err);
        });

module.exports = {
    select
};

以及 HTTP 服务文件:

'use strict';

const port = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const db = require('./db/');

app.use(bodyParser.urlencoded({extended: true}));

app.post('/logdash', db.select);

app.listen(port, function () {
    console.log('Server is running on port', port);
});

代码基于 pg-promise v.4.3.x(升级,如果你有旧版本)。

我不会说这是组织代码的好方法,但至少它是一个工作示例。您可以查看 pg-promise-demo 以获得完整的应用程序示例,它可以让您更好地了解如何组织数据库代码。


API 参考文献:map


几件事。我会确保您的 select 函数 returns 是一个 Promise。我也会处理你路线中的承诺。这样您就可以正确发送适当的状态代码和响应。

db/index.js

'use strict';

const pgp = require('pg-promise')();
const pg = pgp(process.env.DATABASE_URL);

let select = () => {
  return pg.any('SELECT username, status FROM status')
}

module.exports = () => {
    select
};

server.js

'use strict';

const port = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const db = require('./db/');

app.use(bodyParser.urlencoded({extended: true}));

app.post('/logdash', function(req, res, next) {
    db.select()
        .then((data) => {
          res.status(200).json(data)
        })
        .catch((error) => {
          res.status(500).json(error)
        })
});

app.listen(port, function() {
    console.log('Server is running on port', port);
});

我没有对此进行测试,但它应该可以解决问题。