koajs / koa

Expressive middleware for node.js using ES2017 async functions
https://koajs.com
MIT License
35.11k stars 3.22k forks source link

Why does routing fail when asynchronous middleware is used with routing #1745

Closed dong-lufei closed 12 months ago

dong-lufei commented 1 year ago
import Koa from "npm:koa@2.14.1"
import Router from "npm:koa-router@12.0.0"

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

app.use((ctx, next) => {
  const start = Date.now()
  return next().then(() => {
    const ms = Date.now() - start
    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
  })
})
// koa 的中间件示例
function delay(duration) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, duration)
  })
}
// 中间件1
app.use(async function (_ctx, next) {
  console.log(1)
  await next()
  console.log(4)
})

// 中间件2
app.use(async function (_req, _res, _next) {
  console.log(2)
  await delay(1000)
  console.log(3)
})

router.get("/", (ctx, _next) => {
  console.log("home")
  ctx.body = "home"
})

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

app.listen(1993, () => {
  console.log("http://localhost:1993")
})

deno run -A mod.js http://localhost:1993 1 2 3 4 GET / - 1053ms

The page responds with 404 Not Found

iwanofski commented 12 months ago

First of all, I just want to mention that Koa isn't tested against deno by the maintainers as far as I know so bugs might occur even though technically it "should just work" :)

But the reason this has unexpected response is because of this middleware:

// 中间件2
app.use(async function (_req, _res, _next) {
  console.log(2)
  await delay(1000)
  console.log(3)
})

That's not a function signature supported by Koa. Also there's nothing in that middleware calling next so logically the request isn't expected to reach your router (which is added to the middleware chain after said middleware).

iwanofski commented 12 months ago

I am going to assume this is either solved or stale, and so I will close this ticket. If you still have questions feel free to re-open this ticket!