簡體   English   中英

node.js流管道異步或同步

[英]node.js stream pipe asynchronous or synchronous

問題:這是一個問題,就像在learnyounode模塊中jugglingAsync of node.js一樣。 “此問題與上一個問題(HTTP COLLECT)相同,因為您需要使用http.get()。但是,這次您將獲得三個URL作為前三個命令行參數。

您必須收集每個URL提供給您的完整內容,並將其打印到控制台(stdout)。 您不需要打印長度,只需將數據打印為String; 每個網址一行。 問題是您必須按照與作為命令行參數提供給您的URL相同的順序打印它們。“

我嘗試使用node.js stream.readable類來管道從第一個URL到第二個URL的響應以及從第三個URL到第三個URL的響應。 我期待這將同步運行,即當第一個請求完成時,第二個請求將被傳送。 我使用package bl( https://www.npmjs.org/package/bl )來收集get請求的所有響應數據。 下面的代碼片段:

var https = require('http');
var bl = require('bl');
var finalString = '';

https.get( process.argv[2], function(response)
    {
        response.setEncoding('utf8');
        response.pipe(bl(function (err, data)
        {
            console.log("First request called");
            if (err) return console.error(err);
            console.log(data.toString());

        })).pipe(bl(function(err, data)
        {

            console.log("Second Request called");
            https.get (process.argv[3], function( response)
            {
                response.setEncoding('utf8');
                response.pipe(bl( function (err, data)
                {
                    if (err) return console.error(err);                    
                    console.log(data.toString());

                }))
            }).on('error', function(err)
                {
                    console.log(err);
                })
        })).pipe( bl(function(err,data)
            {
                console.log("Third request called");
                https.get (process.argv[4], function( response)
                {

                    response.setEncoding('utf8');
                    response.pipe(bl( function (err, data)
                    {
                        if (err) return console.error(err);                        
                        console.log(data.toString());

                    }))

                }).on('error', function(err)
                    {
                        console.log(err);
                    })
            })
            )
    }).on('error', function (err)
    {
            console.log(err);
    }
);

輸出不遵循請求的順序。 我究竟做錯了什么?

據我所知,Streams {in nodejs }中的pipe是異步的,但我已經讀過某些地方,他們也可以充當同步。 上面的解決方案以異步方式運行,因此以隨機順序打印數據。

您的解決方案可以如下工作: -

var https = require('http');
var bl = require('bl');
var finalData = [];
var count = 0;

https.get( process.argv[2], function(response)
    {
        response.setEncoding('utf8');
        response.pipe(bl(function (err, data)
        {
            // console.log("First request called");
            if (err) return console.error(err);
            finalData[0] = data.toString();
            count++;
            printThemOut(count);

        })).pipe(bl(function(err, data)
        {

            // console.log("Second Request called");
            https.get (process.argv[3], function( response)
            {
                response.setEncoding('utf8');
                response.pipe(bl( function (err, data)
                {
                    if (err) return console.error(err);
                    finalData[1] = data.toString();
                    count++;
                    printThemOut(count);

                }))
            }).on('error', function(err)
                {
                    console.log(err);
                })
        })).pipe( bl(function(err,data)
            {
                // console.log("Third request called");
                https.get (process.argv[4], function( response)
                {

                    response.setEncoding('utf8');
                    response.pipe(bl( function (err, data)
                    {
                        if (err) return console.error(err);
                        finalData[2] = data.toString();
                        count++;
                        printThemOut(count);
                    }))

                }).on('error', function(err)
                    {
                        console.log(err);
                    })
            })
            )
    }).on('error', function (err)
    {
            console.log(err);
    }



);

function printThemOut(count) {
  if (count == 3) {
    for (var i = 0; i < finalData.length; i++) {
      console.log(finalData[i]);
    }
  }
}

上面的解決方案有效,但問題是(在我的情況下),第一個URL調用的第一個數據,第一個單詞丟失。

{我認為在第一個網址的相同數據上使用多個管道的原因}

我們需要一個計數器來索引http.get()獲取的數據,以便第一個URL數據存儲在索引0和第二個1索引中,依此類推。 這有助於同步所有異步數據......

適當的解決方案

正確的解決方案是循環調用並在每個數據上使用單個管道......

var http  = require("http");
var bl    = require("bl");

var completeData = [];
var count = 0;
for (var i = 2; i < process.argv.length; i++) {
  (function(index){
    http.get(process.argv[index], function(res) {
      res.pipe(bl(function(err, data) {
        if (err) {
          return console.log(err);
        }
        // console.log(index);
        completeData[index-2] = data.toString();
        count++;
        // console.log("Data: " + data.toString());
        if (count === process.argv.length-2) {
          printThemOut(completeData);
        }
      }))
    })
  })(i);
}

function printThemOut(data) {
  for (var i = 0; i < data.length; i++) {
    console.log(data[i]);
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM