在节点中使用流(streams2)的新方法是否创建了阻塞



我意识到节点是非阻塞的,但是,我也意识到因为节点只有一个线程,所以在事件循环的中间放置一个三秒的while循环会导致阻塞。 即:

var start = new Date();
console.log('Test 1');
function sleep(time, words) {
    while(new Date().getTime() < start.getTime() + time);
    console.log(words);
}
sleep(3000, 'Test 2'); //This will block
console.log('Test 3') //Logs Test 1, Test 2, Test 3

我看到的许多处理新"Streams2"接口的示例看起来都会导致同样的阻塞。例如这个,从这里借来的:

var crypto = require('crypto');
var fs = require('fs');
var readStream = fs.createReadStream('myfile.txt');
var hash = crypto.createHash('sha1');
readStream
  .on('readable', function () {
    var chunk;
    while (null !== (chunk = readStream.read())) {
      hash.update(chunk); //DOESN'T This Cause Blocking?
    }
  })
  .on('end', function () {
    console.log(hash.digest('hex'));
  });

如果我遵循正确的内容,当缓冲区中有数据时,readStream将发出 readable 事件。 因此,似乎一旦发出readable事件,整个事件循环就会停止,直到readStream.read()发出 null。 这似乎不如旧方法可取(因为它不会阻塞)。有人可以告诉我为什么我错了。 谢谢。

内部流缓冲区为空之前,您不必读取。如果你愿意,你可以只读一次,然后在一段时间后再读另一个块。

readStream.read()本身不是阻塞,但hash.update(chunk)(在短时间内)是因为哈希是在主线程上完成的(关于添加将在线程池中执行加密函数的异步接口存在 github 问题)。

此外,您可以简化使用加密流接口的代码:

var crypto = require('crypto'),
    fs = require('fs');
var readStream = fs.createReadStream('myfile.txt'),
    hasher = crypto.createHash('sha1');
readStream.pipe(hasher).on('readable', function() {
  // the hash stream automatically pushes the digest
  // to the readable side once the writable side is ended
  console.log(this.read());
}).setEncoding('hex');

所有 JS 代码都是单线程的,因此循环会阻塞,但您误解了该循环将运行多长时间。调用 .read() 从流中获取可读项,就像与该项一起调用"数据"处理程序一样。一旦没有项目,它将停止执行并取消阻止。每当有数据时都会触发"可读",然后清空缓冲区并等待另一个"可读"。因此,您的第一个while循环依赖于要更新的时间,这可能是一些无限的时间量,另一个循环基本上是在执行:

 while (items.length > 0) items.pop()

这几乎是处理流中的项目所需的最少工作量。

相关内容

  • 没有找到相关文章

最新更新