【问题标题】:middleware code isn't asynchronous? nodejs express中间件代码不是异步的? nodejs快递
【发布时间】:2020-12-16 09:18:32
【问题描述】:

所以我在玩 node.js 和 express.js...

下面给出了我的 nodejs 代码。 在 '/' 路由中,它将发送一个带有一个文本输入框和一个提交按钮的 html。

你会在下面看到两个我想异步运行的中间件函数

const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');

const PORT = process.env.PORT || 8080
const test = express()

test.use(bodyParser.urlencoded({extended : true}));
test.use(bodyParser.json());
test.use(session({
    secret: 'secret',
    resave: true,
    saveUninitialized: true
}));

test.get('/',(req,res)=>{
    res.send(`
        <!DOCTYPE html><html><head><title>test</title></head><body>
        <form class="loginform" action="/jump" method="POST">
            <input type="text" name="username" placeholder="Your Name" required><br>
            <input type="submit" name="guest-login" value="test" id="guest-login">
        </form></body></html>
    `)
})

test.post('/jump', async (req,res)=>{
    req.session.username = req.body.username;
    req.session.loggedin = true;

    try{
        await first(req)
        await second(req,res)
    }catch(err){
        console.log(err)
    }
})

test.listen(PORT,function(){
    console.log('listening on port : '+PORT)
})

function first(req){
    return new Promise((resolve)=>{
        for(let i=0; i<50000; ++i){
            console.log(req.session.username)
        }
        console.log('loop done')
        resolve()
    })
}

function second(req,res){
    return new Promise((resolve)=>{
        res.send(`<h1>WELCOME ${req.session.username}</h1>`)
        console.log(`DONE ${req.session.username}`)
        resolve()
    })
}

我的问题是,每当我尝试在大致相同的时间向不同的浏览器(例如 chrome 和 firefox)发出不同的发布请求(点击提交)时,节点运行时都会显示我点击“first”的浏览器的用户名",然后它会依次输出下一个……见下例

例如:

firefox
firefox
.
.
.
firefox
firefox
loop done
DONE firefox

chrome
chrome
.
.
.
chrome
chrome
loop done
DONE chrome

上面的例子不是我期望的输出。

据我了解...我期望的输出类似于下面的代码...我在这里做错了什么?

firefox
chrome
chrome
firefox
chrome
firefox
chrome
loop done
firefox
loop done
DONE chrome
DONE firefox

【问题讨论】:

    标签: node.js express asynchronous backend


    【解决方案1】:

    NodeJS 是单线程、非阻塞 I/O,这里实际上单线程忙于在循环内的控制台上打印它实际​​上并没有阻塞。如果循环包含异步任务,如磁盘 I/O、REST 调用或任何异步任务,线程将开始处理另一个请求,并在异步任务完成后返回结果。

    【讨论】:

      【解决方案2】:

      Javascript 只有 1 个线程,并且在 for 循环中您阻止了 event loop。因此,没有执行任何其他代码。

      如果您不进行复杂的计算,Node.js 会非常出色。

      如果你需要做复杂的计算,那么作为这个问题的解决方案你可以看看clustersworker threads上的资料。

      为了更好地理解事件循环,我可以推荐你观看talk这个话题

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多