Nodejs koa-router 是否真的能正常使用 async/await ?

发布于 1周前 作者 yibo5220 来自 nodejs/Nestjs

Nodejs koa-router 是否真的能正常使用 async/await ?

刚才试着用 Koa 2 写个应用,结果在使用 async/await 的时候有点迷糊。

我给自己的应用用 koa-router 这个中间件写了个路由,然后从远程 API 服务器上获取信息:

router.get('/bili/:vid', async (ctx, next) => {
    try {
        var result = await services.bilibili.video(this.params.vid);
        ctx.body = result;
    } catch (e) {
        ctx.body = e;
    }
});

但是在运行测试的时候发现它返回的内容直接是一个空对象,什么都没有,错误也没报:

HTTP GET: /bili/1145140
Response: {}

后来我不使用 router 中间件直接 app.use 发现功能一切正常:

app.use(async (ctx) => {
    ctx.body = await services.bilibili.video(1145140);
});
Response: {"tid":59,"typename":"演奏",...(如下略过)

我确定在远程服务器上获取信息的函数返回的是 Promise 对象:

function getVideoInfo(vid) {
    return new Promise((resolve, reject) => {
        var reqmap = new Map();
        reqmap.set('appkey', config.biliapi.appkey);
        reqmap.set('id', vid);
        reqmap.set('page', 1);
        ...(如下略过)

发现问题后我尝试在 Google 和 GitHub 上查找相关关键词但都没有找到类似的案例,不知道是什么问题造成的。

Koa 版本是 2.2.0 , Koa router 版本是 7.1.1 。


12 回复

所以 router 外部逻辑呢(你只贴了内部逻辑)?一起贴出来



小的不太了解专业术语,不知道外部逻辑和内部逻辑是什么意思,请见谅。

const Koa = require(‘koa’);
const render = require(‘koa-ejs’);
const koaStatic = require(‘koa-static’);
const path = require(‘path’);

const app = new Koa();
render(app, {
root: path.join(__dirname, ‘views’),
layout: false,
viewExt: ‘ejs’
});

app.use(koaStatic(path.join(__dirname, ‘statics’))).use(routers.routes()).use(routers.allowedMethods());

使用到的中间件也就这些了。

用了 arrow function 后 this 不是 router 实例了

刚才把箭头函数打掉了,但返回的内容照样是空对象。

先 use 里那样,直接写死一个 id 试下

s/先 /像

你使用 koa-router , await services.bilibili.video(this.params.vid)的参数是 String ,返回结果的是空{},并没有捕获到异常。
你直接 app.user, await services.bilibili.video(1145140)的参数是 Number ,正确返回结果。
那是不是你的 services 方法有问题呢? 方便的话贴出来看看。
或者直接自己打断点 debug 吧, 顺便说下 koa-router@next 是肯定能正常使用 async/await

果然我又不中用了…
刚才写死 id 之后内容获取正常。
再重新看了下 koa-router 的示例代码,我居然模仿的是旧版本的示例…

遇到过很多次类型情况,让我养成一个习惯:先怀疑自己,再怀疑框架

当然可以 https://github.com/solarhell/journey/blob/master/src/routes.ts

可以在看下 CheckPermission 的写法

当然可以,koa-router 完全支持在路由处理函数中使用 async/await。在 koakoa-router 中使用 async/await 可以让异步代码看起来更像同步代码,从而提高可读性和可维护性。以下是一个简单的示例,展示了如何在 koa-router 中使用 async/await

const Koa = require('koa');
const Router = require('koa-router');

const app = new Koa();
const router = new Router();

// 示例数据库查询函数(模拟)
const fakeDatabaseQuery = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('Data from database');
    }, 1000);
  });
};

// 使用 async/await 的路由处理函数
router.get('/data', async (ctx) => {
  try {
    const data = await fakeDatabaseQuery();
    ctx.body = data;
  } catch (error) {
    ctx.status = 500;
    ctx.body = 'Internal Server Error';
  }
});

app
  .use(router.routes())
  .use(router.allowedMethods());

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

在这个例子中,fakeDatabaseQuery 函数模拟了一个异步的数据库查询。在路由处理函数中,我们使用 await 来等待这个查询完成,并将结果返回给客户端。如果查询过程中发生错误,我们捕获异常并返回 500 状态码。

因此,koa-router 可以正常使用 async/await,这使得处理异步操作变得更加简洁和直观。

回到顶部