Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

koa中间件的执行顺序为什么必须保证洋葱模型? #3

Open
lovelmh13 opened this issue Jul 14, 2019 · 0 comments
Open

Comments

@lovelmh13
Copy link
Owner

首先要知道next的作用:洋葱模型以next为分界线,next之后的代码表明之前的中间件已经执行完成了。

  1. 只有按照洋葱模型执行,才知道什么时候后续的中间件执行完成。需要保证逻辑代码的前提条件能够正常执行

反例:

app.use(async (ctx, next) => { // async特性:函数前写async,会把函数强制包装成一个promise
    console.log(1);
    next(); // next的返回结果是promise
    console.log(2);
})
app.use(async (ctx, next) => { // async特性:函数前写async,会把函数强制包装成一个Promise {  }
    console.log(3);
    await axios.get('http://www.baidu.com');
    console.log(4);
})
// 1 3 2 4 并非洋葱模型,await阻塞了后续console.log(4)的执行,先打印出了2

如果按照上面的代码,一旦我们需要第二个中间执行完以后再去执行console.log(2); 这个顺序就被打乱了。如果第二个中间件是console.log(2);的前提条件,这个条件就没有提到前提条件的作用,后果可想而知。

例如:计算运行时长,需要等到后面的函数执行都完成才能算出来

app.use(async (ctx, next) => {
    const axios = require('axios');
    const start = Date.now();
    const res = await axios.get('http://www.baidu.com');
    const end = Date.now();
    console.log(end-start);
    console.log(res);
});
  1. 保证ctx可以顺利拿到前面中间件所返回的数据

    app.use(async (ctx, next) => {
        console.log(1);
        let a = next();
        console.log(a);
        console.log(2);
    })
    
    app.use(async (ctx, next) => {
        console.log(3);
        next();
        console.log(4);
        return '第二个中间件';
    })
    // 1 3 4 '第二个中间件' 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant