当前位置:网站首页>koa - 洋葱模型浅析
koa - 洋葱模型浅析
2022-06-30 11:16:00 【yanling.zhang】
1.什么是koa?
Koa是一个精简的node框架,被认为是第二代Node框架,其最大的特点就是独特的中间件流程控制,是一个典型的洋葱模型,它的核心工作包括下面两个方面:
将node原生的req和res封装成为一个context对象。基于async/await的中间件洋葱模型机制。
2.koa1和koa2在源码上的区别有何不同?
- Koa1是使用generator、yield的模式。
- Koa2使用的是async/await + Promise的模式。
3.什么是洋葱模型。
Koa的洋葱模型是以next()函数为分割点,先由外到内执行Request的逻辑,然后再由内到外执行Response的逻辑,这里的request的逻辑,我们可以理解为是next之前的内容,response的逻辑是next函数之后的内容,也可以说每一个中间件都有两次处理时机。洋葱模型的核心原理主要是借助compose方法。
如下图:
如下是洋葱代码的案例:
const Koa = require('koa');
//Applications
const app = new Koa();
// 中间件1
app.use((ctx, next) => {
console.log(1);
next();
console.log(2);
});
// 中间件 2
app.use((ctx, next) => {
console.log(3);
next();
console.log(4);
});
app.listen(7000, '0.0.0.0', () => {
console.log(`Server is starting`);
});
// 中间件的打印顺序是1 -> 3 -> 4 -> 2
4.源码解析
- use方法
使用中间件的时候,最先使用use方法,use方法会讲传入的中间件回调函数存储到middleware中间件数组中。
- listen方法
当执行app.listen去监听端口的时候,其实其内部调用了http模块的createServer方法,然后传入内置的callback方法,这个callback方法就会将use方法存储的middleware中间件数组传给compose函数。
- compose方法
compose方法是洋葱模型的核心,compose方法中有一个dispatch方法,第一次调用的时候,执行的是第一个中间件函数,中间件函数执行的时候就是再次调用dispatch函数,也就说形成了一个递归,这就是next函数执行的时候会执行下一个中间件的原因,因此形成了一个洋葱模型。
function compose (middleware) {
// context: 上下文
// next:next函数
return function (context, next) {
// last called middleware #
let index = -1
// 一开始的时候传入为 0,后续会递增
return dispatch(0)
function dispatch (i) {
// 假如没有递增,则说明执行了多次
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i
// 拿到当前的中间件
let fn = middleware[i]
if (i === middleware.length) fn = next
// 当 fn 为空的时候,就会开始执行 next() 后面部分的代码
if (!fn) return Promise.resolve()
try {
// 执行中间件,留意这两个参数,都是中间件的传参,第一个是上下文,第二个是 next 函数
// 也就是说执行 next 的时候也就是调用 dispatch 函数的时候
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err)
}
}
}
}
5.为什么需要洋葱模型?
因为很多时候,在一个app里面有很多中间件,有些中间件需要依赖其他中间件的结果,用葱模型可以保证执行顺序,如果没有洋葱模型,执行顺序可能出乎我们的预期。
边栏推荐
- 什么是微信小程序,带你推开小程序的大门
- Go语言学习之Switch语句的使用
- 科普达人丨漫画图解什么是eRDMA?
- The latest collection of arouter problems
- Understanding society at the age of 14 - reading notes on "happiness at work"
- 暑假学习记录
- 100 important knowledge points that SQL must master: creating and manipulating tables
- A man is a Book
- 据说用了这个,老板连夜把测试开了
- 对象映射 - Mapping.Mapster
猜你喜欢

记一次ViewPager + RecyclerView的内存泄漏

限时预约|6 月 Apache Pulsar 中文开发者与用户组会议

Dameng data rushes to the scientific innovation board, or becomes the "first share of domestic database" in the A-share market

暑假学习记录

Jetpack Compose DropdownMenu跟随手指点击位置显示

Multiparty Cardinality Testing for Threshold Private Set-2021:解读

The operation and maintenance security gateway (Fortress machine) of Qiming star group once again won the first place!

Kongsong (ICT Institute) - cloud security capacity building and trend in the digital age

Evaluation of IP location query interface Ⅲ

Handler-源码分析
随机推荐
Pointdistiller: structured knowledge distillation for efficient and compact 3D detection
[leetcode 16] sum of three numbers
[IC5000 tutorial] - 01- use daqdea graphical debug to debug C code
Evaluation of IP location query interface Ⅲ
Handler source code analysis
Flutter 从零开始 008 表单
线代(高斯消元法、线性基)
The first batch in China! Alibaba cloud native data Lake products have passed the evaluation and certification of the ICT Institute
LiveData源码赏析三 —— 常见问题
Alibaba cloud lifeifei: China's cloud database has taken the lead in many mainstream technological innovations abroad
Methods and usage of promise async and await
The jetpack compose dropdownmenu is displayed following the finger click position
林克庆到番禺区调研“发展要安全”工作 以“时时放心不下”责任感抓好安全发展各项工作
[applet practice series] Introduction to the registration life cycle of the applet framework page
【小程序实战系列】小程序框架 页面注册 生命周期 介绍
It's time for the kotlin coroutine to schedule thread switching to solve the mystery
R language view version R package view version
STM32F407ZGT6使用SDIO方式驱动SD卡
SQL必需掌握的100个重要知识点:组合查询
Retest the cloud native database performance: polardb is still the strongest, while tdsql-c and gaussdb have little change