【问题标题】:Keep order in nodejs command line script在nodejs命令行脚本中保持顺序
【发布时间】:2017-07-16 18:30:50
【问题描述】:

我想在 nodejs 中编写一些代码,但我不知道如何实现它。我一直在阅读和搜索很多,但仍然不知道什么是正确的方法。

问题如下:

  • 从标准输入读取行
  • 对于每一行,启动一个 http 请求
  • 同时http必须有限制
  • 将读取的行加上从 http 请求中获得的一些数据写入标准输出
  • 行必须按顺序写

您不能读取“所有”文件然后拆分行:您必须一次处理一行,记住它是标准输入。你不知道输入什么时候结束。

有人知道如何解决这个问题吗?我不知道如何进行。

【问题讨论】:

  • 有一个async library 来处理同时执行的有限制的请求,然后在所有请求都解决后处理结果。对于请求,您可以使用 npm 模块 requestrequest-promise

标签: javascript node.js io


【解决方案1】:

你可以这样做:

const http = require('http');
const Promise = require('bluebird');
let arrayOfRequests = [];
process.stdin.on('data',  (data) => { 
    //get data from the stdin
    //then add the request to the array
    arrayOfRequests.push(http.get({}))

})

process.stdin.on('end', () => {
    Promise.all(arrayOfRequests)
    // use Promise .all to bundle all of the reuqest
    //then use the spread operator so you can use all of the reuqest In order
    .spread( (request1,request2,request3)  => {
        // do stuff
    })
})

仅供参考,sn-p 不起作用。

所以你正在做的是使用 Node.js 中内置的 process.stdin。然后,您将捆绑所有请求。每当用户取消程序时,都会提出您的请求。由于调用将是异步的,因此您将它们放在一个数组中,然后运行 ​​Promsise.all 并使用 bluebird .spread 运算符解构 Promise.all 并获取值。

【讨论】:

  • 是的,这行得通,但我想避免在处理之前读取所有输入。如果文件很大怎么办?我认为需要类似于阻塞队列的东西,我正在研究。
  • 我知道你想使用 BQ 作为 DS,但你实际上想做什么?你想读入整个文件,解析文件,触发所有 http 请求(向上到一定限度),然后打印出来?
  • 不,我想读取文件的一些行,在一定的限制下触发 http 请求,当请求完成后,再读取文件的更多行,等等。
【解决方案2】:

到目前为止,我已经为 nodejs 中的生产者 - 消费者问题提供了这个解决方案,其中生产者在队列中有可用空间之前不会产生更多数据。

这是队列的代码,基于block-queue: https://gist.github.com/AlvaroMaceda/8a933a317fed3fd4691fd5eda3e60c5e

要使用阻塞队列,请使用 3 个参数创建它:

  1. 并发运行的任务数
  2. “推送”功能。它将以队列作为参数调用 需要更多数据。该任务将添加一个标识符。
  3. “任务”功能。它将使用创建的标识符调用 “推送”功能。

只有在需要更多数据时,队列才会调用“推送”。例如,如果有 5 个任务正在运行,并且创建时最多有 5 个并发任务,则在其中一个任务结束之前不会调用“push”。

这是一个如何使用它的示例:

"use strict";
const queue = require('./block-queue');

const CONCURRENCY = 5;
const WORKS_TO_LAUNCH = 10;
const TIMEOUT = 200;

let i = 1;
let q = queue(CONCURRENCY, doSomethingAsync, putMoreData );

function putMoreData(queue) {
    if (++i <= WORKS_TO_LAUNCH) {
        console.log('Pushing to queue');
        queue.push(i);
    }
}
function doSomethingAsync(task, done) {
    setTimeout(function() {
        console.log('done ' + task);
        done();
    }, 1000 + task * TIMEOUT);
}

q.push(i);

我不认为这是已解决的,因为我不知道是否有更简单的方法并且我想使用完整的解决方案,不知道在使用它和流时我是否会发现一些问题.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 2015-10-12
    相关资源
    最近更新 更多