nodejs Express API中的端点是否阻止其他端点访问?

lnlaulya  于 2022-12-03  发布在  Node.js
关注(0)|答案(1)|浏览(130)

嗨,我是Nodejs和Express的新手。
我有两个端点/addcar /viewcar
我做了一个无限循环,每当post调用被发送到/addcar时运行,同时尝试点击/viewcar来检查它是否并行工作。但是对/viewcar的请求超时了。所以我也添加了async关键字来检查。仍然是同样的问题。

app.post('/addcar',async function(req,res){
    console.log(req.body);

    let a =100;
    while(a>10){
        console.log("iterating");
    }
    res.end();
})
app.get('/viewcar',(req,res)=>{
    res.send('hello');
})

但是/viewcar必须并行工作,即使一个端点函数连续运行,对吗?我做错了什么?如果这个问题很愚蠢,对不起。

ubof19bj

ubof19bj1#

js是单线程的。因此任何长循环都会阻塞整个进程。无限循环肯定会阻塞服务器。
node.js中的长期建议是**don't block the event loop!**
如果你需要执行一个长时间运行的进程,你需要将它分成多个块,允许事件循环运行(例如,使用setTimeout()),或者使用web worker产生一个新的线程。
node.js的单线程特性并不是一个bug。它是故意的,并且是node.js快速和轻量级的原因。虽然多线程确实简单地解决了并行问题,但它有上下文切换和高内存使用的代价(这反过来也可能由于分配内存和垃圾收集而导致速度下降)。

将长时间运行的进程拆分为异步块

正如上面所暗示的,你可以将长时间运行的循环拆分成块,然后异步运行它们。

function infiniteLoop (message) {
    console.log("iterating" + message);

    setTimeout(()=>infiniteLoop(message), 10); // run 100 times per second
}

app.post('/addcar',async function(req,res){
    console.log(req.body);

    infiniteLoop(JSON.stringify(req.body));

    res.end();
})

通过对setTimeout函数进行promitiating并使用async/await,可以使代码看起来更像一个循环:

function sleep (timeout) {
    return new Promise(ok => setTimeout(ok, timeout));
}

app.post('/addcar',async function(req,res){
    console.log(req.body);

    let a =100;
    while(a>10){
        console.log("iterating");
        await sleep(10); // this allows the event loop to run
    }
    res.end();
})

大多数需要很长时间的事情已经是异步的

一般来说,除非你要计算π(pi)的第1000位数,否则大多数需要等待很长时间的事情都是异步的,因此阅读文件或查询数据库等操作不会阻碍这个过程:

app.post('/addcar',async function(req,res){
    console.log(req.body);

    // This does not block other endpoints:
    let data = await db.query('select * from products');        

    res.json(data);
})

这是因为等待I/O根本不占用CPU,因此node.js可以在数据通过网络传输到您的PC时执行其他javascript代码(例如其他端点)。
基本上,唯一需要考虑这个问题的时候是当你需要运行长的forwhile循环的时候。

相关问题