在基于PHP(或Java/ASP.NET/Ruby)的Web服务器中,每个客户端请求都在新线程上实例化.但是在Node.js中,所有客户端都运行在同一个线程上(它们甚至可以共享相同的变量!)我知道I/O操作是基于事件的,所以它们不会阻塞主线程循环.
我不明白的是为什么Node的作者选择它是单线程的?这让事情变得困难.例如,我无法运行CPU密集型功能,因为它阻塞了主线程(并阻止了新的客户端请求),因此我需要生成一个进程(这意味着我需要创建一个单独的JavaScript文件并在其上执行另一个节点进程) ).但是在PHP中,cpu密集型任务不会阻止其他客户端,因为我提到每个客户端都在不同的线程上.与多线程Web服务器相比,它有哪些优势?
注意:我已经使用群集来解决这个问题,但它并不漂亮.
我正在尝试学习nodejs和我正在工作的一个小项目正在编写一个API来控制一些联网的LED灯.
控制LED的微处理器具有处理延迟,我需要将发送到微处理器的命令间隔至少100ms.在C#中,我习惯只调用Thread.Sleep(时间),但我没有在节点中找到类似的功能.
我在节点中使用setTimeout(...)函数找到了几个解决方案,但是,这是异步的并且不会阻塞线程(这是我在这种情况下所需要的).
有人知道阻塞睡眠或延迟功能吗?最好是不仅能旋转CPU,而且精度为+ -10 ms的东西?
在过去的几个小时里,我一直试图绕过这个问题,但无法理解.我想我还是要习惯函数式编程风格;)
我编写了一个递归函数,遍历目录结构并对某些文件执行操作.此函数使用异步IO方法.现在我想在整个遍历完成时执行一些操作.
如何在执行所有parse
调用但仍使用异步IO功能后确保执行此操作?
var fs = require('fs'),
path = require('path');
function parse(dir) {
fs.readdir(dir, function (err, files) {
if (err) {
console.error(err);
} else {
// f = filename, p = path
var each = function (f, p) {
return function (err, stats) {
if (err) {
console.error(err);
} else {
if (stats.isDirectory()) {
parse(p);
} else if (stats.isFile()) {
// do some stuff
}
}
};
};
var i;
for (i = 0; i < files.length; i++) …
Run Code Online (Sandbox Code Playgroud) 我试图在JavaScript和Node.js中了解生成器和产量,但是遇到了问题.
理想情况下,我想要做的是用生成器/ yield包装fs.readFile,这样我就可以同步使用它而不会阻塞任何东西.
我想出了以下代码:
function readFileSync (path) {
return (function *(){
return yield require('fs').readFile(path, function *(err, data){
yield data;
});
})();
}
console.log(readFileSync('test-file.txt'));
Run Code Online (Sandbox Code Playgroud)
但是,不幸的是,readFileSync
只是总是返回{}
而不是文件内容.
希望我想要实现的目标仍然是可能的,或者我可能完全错过了生成器/产量的点,我完全错误地使用它,在这种情况下指出我出错的地方,任何资源都会很棒.
正如牛仔在这里的评论中所说,我们都想"以类似于这样的风格编写[非阻塞JavaScript]异步代码:
try
{
var foo = getSomething(); // async call that would normally block
var bar = doSomething(foo);
console.log(bar);
}
catch (error)
{
console.error(error);
}
Run Code Online (Sandbox Code Playgroud)
"
所以人们已经提出了解决这个问题的方法
但是这些都没有导致代码像上面的同步样式代码一样简单易懂.
那么为什么javascript编译器/解释器不能阻止我们目前称为"阻塞"的语句呢?那么,为什么javascript编译器/解释器无法处理AS上面的同步语法,如果我们以异步方式编写它?"
例如,在getSomething()
上面的处理中,编译器/解释器可以只说"这个语句是对[文件系统/网络资源/ ...]的调用,所以我会做一个注释来听取来自该调用的响应和同时继续我的事件循环中的任何东西".当调用返回时,执行可以继续doSomething()
.
您仍然可以维护流行的JavaScript运行时环境的所有基本功能
这只是对语法的一种调整,这将允许解释器在IT DETECTS一个异步操作时暂停执行任何给定的代码位,而不是需要回调,代码只是在调用异步调用后从行继续执行回报.
正如杰里米所说
JavaScript运行时中没有任何内容可以预先暂停执行给定任务,允许其他代码执行一段时间,然后恢复原始任务
为什么不?(如同,"为什么不能有?"......我对历史课不感兴趣)
为什么开发人员必须关心语句是否阻塞?计算机用于自动化人类擅长的东西(例如编写非阻塞代码).
您也许可以实现它
"use noblock"
; "use strict";
)打开整个代码页的"模式".编辑:"use noblock"
; 这是一个糟糕的选择,误导了一些回答者,我试图完全改变常见的JavaScript运行时的性质.喜欢的东西'use syncsyntax';
可能会更好地描述它.parallel(fn, fn, ...); …
node.js ×5
javascript ×4
asynchronous ×2
blocking ×1
ecmascript-6 ×1
generator ×1
sleep ×1
timedelay ×1
yield ×1