有啥方法可以在不使用 Nest.js 中的 async/await 的情况下从数据库中获取数据?

Posted

技术标签:

【中文标题】有啥方法可以在不使用 Nest.js 中的 async/await 的情况下从数据库中获取数据?【英文标题】:Is there any way to get data from the database without using async/await in Nest.js?有什么方法可以在不使用 Nest.js 中的 async/await 的情况下从数据库中获取数据? 【发布时间】:2020-04-07 12:00:26 【问题描述】:

有没有办法使用回调函数在nest.js中使用typeorm从数据库中获取数据并处理该数据,之后我想发送一个响应。

【问题讨论】:

.then(),但你为什么要这么做? 我想从查询的回调中返回服务函数输出。如果我们对查询使用 await ,那么我们的系统执行会等待其输出而不是执行其他任务。 如果是这样的话,我认为您没有正确使用 await。 在主键重复值的情况下,在等待中,如何捕捉到查询的错误? 一个简单的try/catch 围绕你的awaits 就可以了。 【参考方案1】:

看起来 TypeORM 以及大多数现代 JS 包在构建时都只考虑了 Promise。在大多数情况下,除非绝对必要,否则今天的许多程序中都不会使用回调,因为 Promise 和 async/await 语法使代码比使用回调时可能进入的回调地狱更清晰、更易读。看起来sequelize 确实接受了回调,并且配方部分中有一些关于how to use NestJS with Sequelize 的文档

【讨论】:

Nestjs 和 TypeORM 都使用 Observables。 Observables,是的,但是一般的回调,不是。许多人(包括我自己)认为 RxJS 与 javascript 回调不同。【参考方案2】:

答案是您可以使用可观察对象和/或承诺(异步等待)。我经常为包装函数使用 observable,然后承诺在管道中进行附加工作。我不知道为什么我不对所有事情都使用 observables,但这没关系。

TypeORM 与 Nestjs 完美集成,文档展示了如何进行基础操作。使用 Postgres 时,我正在尝试解决的数组存在问题。一个 SO 帖子和一个 Github 问题没有得到答复。

【讨论】:

不要误会我的意思,我认为 Observables 很棒而且非常强大,但我不确定将数据库调用包装在 observable 中是 OP 正在寻找的答案。我认为他们正在寻找更多类似myRepository.create(myObject, (err, result) => ) 风格的回调。 杰伊,我一直尊重你的意见。但几周前我用一个 observable 解决了这个问题。我做了一些重构并回到了一个承诺,因为我已经有了那个代码。我是一个非常糟糕的开发人员,我复制并粘贴了我的旧代码并重用它,而不是每次都采取新的观点。 :-) 我对使用 Observables 或 Promise 没有任何问题,实际上我非常喜欢使用它们。我的大部分 NestJS 服务器都使用 Observables 运行。我要说的是,似乎 OP 正在寻找常规样式的回调,为错误和完成传递一个函数,而不是在 Observable 中包装一个 Promise 函数【参考方案3】:

我不确定我是否正确理解了您的问题,但是开箱即用,您可以使用 TypeORM(假设您使用 SQL DB,但 Mongoose 的工作方式类似)。存储库函数返回一个Promise<>,所以你可以使用这样的东西(来自docs):

return this.photoRepository
           .find()
           .then(result => //... your callback code goes here...
            );

您可以将此代码包装在function getModifiedResult(cb) 中并将回调传递给它。其次,记住async/await只是promise的语法糖,所以上面的等价于:

result = await this.photoRepository.find();
cbAction = //... do something with your result here
return cbAction;

再一次,你可以把它包起来。 另一个想法是使用 RxJS from 操作符将 promise 包装在 Observable 中(fromPromise 用于 RxJS 版本

//... Note that this returns a subscription for you to unsubscribe.
return from(this.photoRepository
           .find()
           .then(result => result))
           .subscribe(result => //... your callback code
            );

但是,如果您走这条路,则可能值得使用 RxJS 运算符修改您的结果,例如 map, switchMap,...

【讨论】:

【参考方案4】:

这与 Nest 本身没有太大关系,它只是您编写代码和处理您可能拥有的任何库的方式。假设你有一个带有回调的数据库获取函数:

function findUsersWithCallback(function callback() 
  // do something with db
  callback(err, results);
);

你可以把它包装成一个类似promise的函数,比如util.promisify

const findUsersPromisified = require('util').promisify(findUsersWithCallback);

剩下的就是使用您的标准 Nest 提供程序:

@Injectable() UsersService 
  findUsers() 
    return findUsersPromisified();
  

现在您的 UsersService 的行为与框架的其余部分一样,并且您的旧的基于回调的代码被很好地包装,因此您可以放心地忽略它。

【讨论】:

【参考方案5】:

您可以只使用 rxjs 中的 from/of 运算符。 示例

create(user: UserInterface): Observable<UserInterface> 
    return from(this.userRepository.save(newUser))

如果你愿意,你也可以通过管道输出结果

create(user: UserInterface): Observable<UserInterface> 
    return from(this.userRepository.save(user)).pipe(
          map((user: UserInterface) => user))
    )

【讨论】:

以上是关于有啥方法可以在不使用 Nest.js 中的 async/await 的情况下从数据库中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章

在 Nest.js 中接受表单数据

Nest.js 获取注入器实例

Nest.Js 不接受任何更改

Nest.js 为模型创建静态和实例函数的方法是啥?

Nest.js 中的 Socket.io 确认

如何正确使用 Nest.js 的 @Headers?