@
zbinlin 感谢大佬的解答,我向 ChatGPT 询问了事件循环的阶段
1. Timers 阶段:处理定时器相关的回调函数,例如 setTimeout() 和 setInterval() 的回调。
2. Pending I/O 阶段:处理某些系统操作的回调函数,例如网络请求、文件 I/O 等待的回调。
Idle, Prepare 阶段:内部使用,忽略。
3. Poll 阶段:处理除了定时器和 I/O 之外的回调函数。在这个阶段,Node.js 会检查是否有新的 I/O 事件、计时器到期或者进入了一些回调函数的 setImmediate()。
4. Check 阶段:处理通过 setImmediate() 注册的回调函数。
5. Close Callbacks 阶段:处理通过 close 事件注册的回调函数,例如关闭的文件描述符或者套接字的回调。
然后尝试了,在 `/users/:id` 重现错误
router.get("/users/:id", (ctx) => {
const id =
ctx.request.params.id;
Promise.resolve().then(() => {
ctx.body = id;
});
setTimeout(() => {
ctx.body = id;
}, 1000);
process.nextTick(() => {
ctx.body = id;
});
// ctx.body = id;
});
我现在的理解是,我的代码中, authMiddleware 中间件,因为同步执行,没有等待 next() 函数的结果,也就是不能获取到
` /upload ` 中间件中的 `ctx.body = "upload"`, 在 koa 源码中,进入了 `catch` 返回 404 Not Found
```js
handleRequest(ctx, fnMiddleware) {
const res = ctx.res;
res.statusCode = 404; // 修改为 401
const onerror = err => ctx.onerror(err);
const handleResponse = () => respond(ctx);
onFinished(res, onerror);
return fnMiddleware(ctx).then(handleResponse).catch(onerror);
}
```
在修改了 `res.statusCode = 401` 后, 确实也能在客户端接收到 401 的错误, 根据 koa 的源码,响应结果会在所有中间件执行完毕后,在 then 中执行回调,所以 setImmediate, setTimeout 会在响应之后执行,无法实现对 ctx.body 赋值,完成响应.
不知道我的理解是否正确, 现在疑惑的是, nextTick 为什么没在 then 中注册的回调函数之前执行呢?