如何从一个node模块中导出异步函数

9

我希望编写一个Node.js模块来处理我的各种数据库调用。我想尽可能多地使用async/await,但是遇到了一些问题。

我已经有一些使用Promise的函数,并且成功导出它们。

例如:

function GetUsernames() {
    return new Promise(function (resolve, reject) {
        sql.connect(config).then(function () {
            new sql.Request()
                .query("SELECT [UserName] FROM [Users] ORDER BY [LastLogin] ASC").then(function (recordset) {
                    resolve(recordset);
                }).catch(function (err) {
                    reject(err);
                });
        });
    });
}

然后我按照以下方式进行导出:

module.exports = {
    GetUsernames: GetUsernames,
    GetScopes: GetScopes,
    UpdateToken: UpdateToken,
    SetOwner: SetOwner
};

但是,如何使用异步函数,在node7中使用可用的async/await呢?

我是否仍然只返回一个promise?我尝试过这样做,但是当我在我的代码中调用它时,它不起作用。

const db = require("dataprovider");
...
var result = await db.GetUsernames();

我得到的错误信息:

SyntaxError:意外的标识符

它出现在数据库名称上(如果仅使用promise函数,使用then()则正常工作)。

也许我的谷歌搜索技能很糟糕,但我没有找到任何有用的东西来解决此问题。

我该如何在模块中创建一个异步函数,以便可以在其他地方等待它?

3个回答

11

3
我不确定这样做如何解决module.exports的问题,您能否详细说明一下? - deejbee
2
抱歉之前表述不够清晰。你可以有两种选择,使用上面的代码,然后添加: Module.exports = { getUserNames: getUserNames }或者你可以直接在模块导出中定义函数: module.exports = { getUserNames: async function () { return await db.getUserNames(); } } - Kevin Williams

3

async-await模式真的让你的代码更易读。但是Node不允许全局等待。你只能等待异步流程。你试图做的是在异步流程之外等待。这是不允许的,这是一种反模式的Node应用程序。处理承诺时,我们实际上是在程序中生成异步流程。我们的程序继续执行而不等待Promise。因此,您可以将函数导出为异步,但不能在异步流程之外等待它们。例如。

const db = require('dataprovider');
...
let result = (async () => await db.GetUserNames())();
console.log(result); // outputs: Promise { <pending> }

因此,异步等待模式适用于异步流程。因此,请在异步函数中使用它们,以便节点可以异步执行它们。此外,您也可以等待 Promise。例如。
let fn = async () => await new Promise( (resolve, reject)=>{...} );
fn().then(...);

你创建了一个异步函数'fn'。这个函数是可thenable的。同时,你可以在另一个异步函数中等待'fn'。

let anotherFn = async () => await fn();
anotherFn().then(...);

在这里,我们正在等待一个异步函数内部的异步函数。异步等待模式使您的代码易读且简洁。这在大型项目中得到体现。


0
假设您在baseoperation.ts中有以下函数:
async function GetAllwithFilter(keyword?: any){
//... async job here
}

如果您想要实现这个功能,只需在baseoperation.ta的末尾添加以下代码:

module.exports = { GetAllOrAnyName: GetAllwithFilter}

然后在所需的类中调用它即可:

const objname = require('./baseoperation');

而要在使用Express和Router的API中调用它,您可以使用route函数与get一起使用,因为它接受直接的Promise调用。

router.route('/').get((req,res) => { objname.GetUsernames().then(then(result => {
    res.json(result[0]);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接