nodeJS 等待无法承诺的事件

nodeJS wait for event that cannot be promisified

本文关键字:事件 承诺 等待 nodeJS      更新时间:2023-09-26

我正在尝试从我的nodejs文件中读取STDIN管道,并向URL发出POST请求,其中每一行都给定了STDIN,然后等待响应,读取下一行,发送,等待等。

'use strict';
const http = require('http');
const rl = require('readline').createInterface(process.stdin,null);
rl.on('line', function (line) {
     makeRequest(line); // I need to wait calling the next callback untill the previous finishes
}).on('close',function(){
    process.exit(0);
});

问题是,rl.on('line')会立即从我的管道中读取数千行,并立即发出数千个请求,这将导致EMFILE异常。我知道这是非阻塞 IO 的预期行为,但在这种情况下,不能使用 promises/futures,因为 .on('line') 本身就是一个回调,我无法在不丢失输入数据的情况下操纵它不触发。那么,如果不能使用回调并且超时黑客不够优雅,如何才能摆脱非blockIO的魔咒呢?

保留活动请求的计数器(发送时递增,响应时递减)。一旦计数器超过一个常量(比如 200),(检查每个"行"事件)调用 rl.pause()。在每个响应中,检查计数器是否小于常量,如果是,则调用 rl.resume()。这应该会限制内存中的请求速率和当前行,并解决您的问题。

Node的readline类具有pauseresume函数,这些函数服从底层stream等效项。这些函数专门用于限制管道的某些部分,以帮助解决瓶颈问题。请参阅stream.Readable.pause文档中的以下示例:

var readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
  console.log('got %d bytes of data', chunk.length);
  readable.pause();
  console.log('there will be no more data for 1 second');
  setTimeout(() => {
    console.log('now data will start flowing again');
    readable.resume();
  }, 1000);
});

这使您可以精细控制流入 URL 提取代码的数据量。