说说我对Nodejs的小见解

说说我对Nodejs的小见解

其实主要是对于异步的一个见解把。

很多人说node异步怎么怎么好,可以解决并发量大的问题。

的确,这是node吸引我的其中一个地方。

也许是我浅薄了,怎么也想不明白,不管三七二十一,全部都用异步,合适么?其中一个是打乱了代码本身的流程结构性。

异步固然好,但是对我来说,只需要在接受请求的时候,将其异步一下给回调函数即可,而在这个回调函数里面,我们完完全全可以直接用同步的方式来执行了。因为对于这个人来说,他的访问卡不卡已经影响不到别人了。而对于他自己来说,难道你异步了就能更快很多了?不也还是得执行完了,然后执行回调函数的时候那个人才能看到你返回给他的一些渲染数据?

所以我个人认为在接受请求的时候异步一下就够了。

以上完全为个人的浅薄见解,还希望各位大神帮忙解释一下一些微妙之处,比如各种异步。谢谢。


12 回复

当然,我可以帮助你撰写关于Node.js异步编程的小见解,并提供一些示例代码来解释。

标题:说说我对Nodejs的小见解

内容:


异步编程的思考

其实主要是对于异步编程的一个见解吧。

很多人说Node.js异步编程如何如何强大,可以很好地解决并发量大的问题。的确,这是Node.js吸引我的一个重要原因。

然而,异步编程并非万能药。也许我还不够深刻,但总感觉如果所有代码都采用异步方式,可能会打乱代码的逻辑结构。例如,原本顺序执行的代码逻辑被分散到了多个回调函数中,这会使代码难以理解和维护。

接受请求时的异步

在我看来,只需要在接受请求的时候将其异步处理,之后的业务逻辑则可以使用同步的方式来编写。这是因为对于每个用户的请求,其处理时间不会对其他用户产生显著影响。而用户感知到的响应速度主要取决于服务器处理请求的时间,而不是异步与否。

举个简单的例子:

const http = require('http');

const server = http.createServer((req, res) => {
    // 在这里将请求处理异步化
    processRequest(req, res);
});

function processRequest(req, res) {
    console.log("开始处理请求");

    // 模拟一个耗时操作
    setTimeout(() => {
        console.log("耗时操作完成");
        res.end("Hello, world!");
    }, 2000);

    // 这里可以继续写同步代码
    console.log("同步代码继续执行");
}

server.listen(3000, () => {
    console.log("服务器运行在 http://localhost:3000/");
});

在这个例子中,processRequest 函数内部的 setTimeout 是异步的,它模拟了一个耗时的操作。而在 setTimeout 之后的部分则是同步执行的。

总结

以上完全是个人的一点浅见。虽然Node.js提供了强大的异步编程能力,但在实际开发中,我们仍然可以根据实际情况选择合适的编程方式。对于接受请求这一环节,可以考虑使用异步处理;而在处理具体业务逻辑时,则可以采用同步的方式,以保持代码的可读性和可维护性。

希望各位大神能够分享一些更深入的理解和经验,特别是关于各种异步模式(如Promise、async/await等)的应用场景和优缺点。谢谢!


希望这段内容能满足你的需求,如果有任何修改或补充的需求,请随时告诉我!


最近也一直痴迷于Node.js,根据我的理解,node.js的异步并不能使客户端访问页面变得更快。 它能提供的好处是,可以使服务器的吞吐量变大,也就是说在同一时间内能接受的请求更多。如果原来有很多台服务器来处理大量的并发,用node.js后也许只需要一台或者几台就够了,节约了服务器的成本

像你所说的如果只是在接受请求的时候异步一下,然后就使用回调函数。回调函数也是在js的主线程里跑的,如果回调函数里有同步IO操作,那么主线程必然受阻,导致后边的请求都没有办法及时处理,还是没有能充分利用CPU

node是单线程。所以如果不想瓶颈出现,就是得尽量去异步。不然万一哪怕有0.5秒的卡住,那你的server服务能力就立即变成 2 resp/s。

照你这么说回调函数的回调函数难道就不是在主线程跑了?

更正一下: 对于node.js还需要有一个正确地理解就是,node.js 是非I/O阻塞,而不是非cpu阻塞。 发现这个论坛不能原文更改。

看到你致力于mongodb等一些操作的同步化,就感觉没有理解node.js:) 其实要了解node.js还是要真正理解http和javascript。. 对于web服务端,我们都知道有Apache和Nginx。 我们也知道php和Apache是一对。 但我们更需要了解 CGI(Common Gateway Interface),php就是采用的fastcgi,fastcgi是多线程,通常一个服务器可以开多个线程,php每一次请求都会开一个服务器进程,每个线程内都是独立的,一个线程的崩溃就会影响到另外一个线程,无论如何你开的线程都是有限的,所以在高并发面前还是有所限制(指单台服务器)。 而Nginx公认为比Apache更快,Nginx就是采用的单线程模型,也就是所有的请求都是在一个线程里面。 我们回到node.js,node.js是单线程,这个线程是主线程,但os所有的服务又是独立的进程,例如I/O操作和数据库操作,node.js的主线程就是一个事件队列,当发生一个请求后,node.js只是在这个事件队列中注册一个事件,然后就不管了,具体这个事件的执行就交给了os(i/o,database),等os完成后,通过回调事制(node.js会轮询)再回到主线程的处理,这样就加加提高了并发能力,因为所有的处理都是在一个线程里(开一个线程需要太多额外的消耗)。 对于node.js还需要有一个正确地理解就是,node.js 是非I/O阻塞,而不是非cpu阻塞,也就你阻塞了cpu话,例如在node.js代码中第一个请求for(很大的循环)或while就会发现第二个请求会在第一个请求结束后才会执行(主线程阻塞了),这点非常重要(所以在node.js遇到时间长的运算,一定要做成分拆,做成回调的形式)。 那么node.js会出现cpu阻塞,是不是性能就会有问题呢?不是的,就象Nginx一样,因为对web而言运算是非常非常小的,一次I/O的操作的时候远大于你做10万次的for循环。 从根本去理解node.js的进程就能够找到node.js的应用场景。

昨天看到一篇@老赵 的文章, 觉得 Node 也是类似 http://www.ituring.com.cn/article/37181

我们知道,操作系统的最小调度单元是“线程”,要执行任何一段代码,都必须落实到“线程”上。可惜线程太重,资源占用太高,频繁创建销毁会带来比较严重的性能问题,于是又诞生出线程池之类的常见使用模式。也是类似的原因,“阻塞”一个线程往往不是一个好主意,因为线程虽然暂停了,但是它所占用的资源还在。线程的暂停和继续对于调度器都会带来压力,而且线程越多,调度时的开销便越大,这其中的平衡很难把握。

正因为如此,也有人提出并实现了fiber或coroutine这样的东西,所谓fiber便是一个比线程更小的代码执行单位,假如说“线程”是用来计算的“物理”资源,那么fiber就可以认为是计算的“逻辑”资源了。从理念上说,goroutine和WebWorker都是类似fiber或coroutine这样的概念(所以叫做goroutine):它们都是执行逻辑的计算单元,我们可以创建大量此类单元而不用担心占用过多资源,自有调度器来使用一个或多个线程来执行它们的逻辑。

这样就明白了嘛。

但是阻塞对于代码结构设计来说还是比较头疼的一件事。本来我只是想写一个在node下非常方便的框架而已。

更正一下,很重要 php每一次请求都会开一个服务器进程,每个线程内都是独立的,一个线程的崩溃不会影响到另外一个线程

一图胜千言,为什么要异步。答案是IO相比CPU慢太多了。让CPU不等待IO,提升CPU的利用率。

对于分布式应用,网络IO是很常见的操作。假想下一个页面的渲染要从网络中读10次数据。如果是同步的方式做,时间消耗是线性增长的。而异步达到的并行效果,能显著缩短时间消耗。

异步带来的好处是,提升CPU利用率(主线程的),并发IO,使得压榨更多底层服务的资源。

标题:说说我对Nodejs的小见解

内容: 我主要想谈谈关于Node.js中的异步编程的理解。

确实,很多人提到Node.js时都会强调它的异步特性,认为这能很好地解决高并发的问题。在我看来,异步编程确实是Node.js的一个非常强大的特点,它使得我们可以高效地处理大量的并发请求。

不过,我也有一些不同的看法。有些人认为所有操作都应该尽可能使用异步的方式,但我觉得这不一定是最优的选择。虽然异步编程能够提高应用的整体性能,但如果每个操作都采用异步方式,可能会让代码变得复杂且难以理解和维护。特别是在一些简单的逻辑中,如果强制使用异步方式,反而会增加代码的复杂性,同时也会打乱代码本身的结构性。

我个人的观点是在处理客户端请求时采用异步方式是合理的,而在内部逻辑处理上则可以使用同步方式。因为在处理一个请求的过程中,异步调用并不会阻塞主线程,从而允许其他请求继续处理。但是,在这个过程中我们完成的一些内部逻辑可以完全使用同步的方式实现。因为这些逻辑只会影响到当前请求的处理结果,并不会对其他用户产生影响。举个例子:

app.get('/some-route', async (req, res) => {
  try {
    const data = await fetchDataFromDatabase();
    const processedData = processDataSync(data);
    res.send(processedData);
  } catch (err) {
    console.error(err);
    res.status(500).send('Error processing request');
  }
});

function processDataSync(data) {
  // 这里假设这是一个复杂的同步数据处理过程
  return data.map(item => item * 2); // 简化示例
}

在这个例子中,fetchDataFromDatabase() 是一个异步函数,用于从数据库获取数据;而 processDataSync() 是一个同步函数,用于处理数据。这样,我们在接受请求时使用了异步方式来提高效率,而在处理内部逻辑时采用了同步方式以保持代码清晰易读。

以上只是我个人的一些浅见,希望各位同行能给予指正和补充。

回到顶部