NodeJS有难度的面试题(能答对几个)

2020-06-17 05:29:46易采站长站整理

上面是在网上找的一个示意图,就是说中间件执行就像洋葱一样,最早use的中间件,就放在最外层。处理顺序从左到右,左边接收一个request,右边输出返回response

一般的中间件都会执行两次,调用next之前为第一次,调用next时把控制传递给下游的下一个中间件。当下游不再有中间件或者没有执行next函数时,就将依次恢复上游中间件的行为,让上游中间件执行next之后的代码

例如下面这段代码


const Koa = require('koa')
const app = new Koa()
app.use((ctx, next) => {
console.log(1)
next()
console.log(3)
})
app.use((ctx) => {
console.log(2)
})
app.listen(3001)
执行结果是1=>2=>3

koa中间件实现源码大致思路如下:


// 注意其中的compose函数,这个函数是实现中间件洋葱模型的关键
// 场景模拟
// 异步 promise 模拟
const delay = async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 2000);
});
}
// 中间间模拟
const fn1 = async (ctx, next) => {
console.log(1);
await next();
console.log(2);
}
const fn2 = async (ctx, next) => {
console.log(3);
await delay();
await next();
console.log(4);
}
const fn3 = async (ctx, next) => {
console.log(5);
}

const middlewares = [fn1, fn2, fn3];

// compose 实现洋葱模型
const compose = (middlewares, ctx) => {
const dispatch = (i) => {
let fn = middlewares[i];
if(!fn){ return Promise.resolve() }
return Promise.resolve(fn(ctx, () => {
return dispatch(i+1);
}));
}
return dispatch(0);
}

compose(middlewares, 1);

9、其它

现在在重新过一遍node 12版本的主要API,有很多新发现,比如说

fs.watch这个模块,事件的回调函数有一个参数是触发的事件名称,但是呢,无论我增删改,都是触发rename事件(如果更改是update事件,删除delete事件,重命名是rename事件,这样语义明晰该多好)。后来网上找到一个node-watch模块,此模块增删改都有对应的事件, 并且还高效的支持递归watch 文件。
util模块有个promisify方法,可以让一个遵循异常优先的回调风格的函数,即 (err, value) => … 回调函数是最后一个参数,返回一个返回值是一个 promise 版本的函数。


const util = require('util');
const fs = require('fs');

const stat = util.promisify(fs.stat);
stat('.').then((stats) => {
// 处理 `stats`。
}).catch((error) => {
// 处理错误。
});

9.1 杂想