gpt4 book ai didi

javascript - node.js 流管道异步或同步

转载 作者:搜寻专家 更新时间:2023-10-31 22:50:19 27 4
gpt4 key购买 nike

问题:这是node.js的learnyounode模块JugglingAsync中的问题。“这个问题与之前的问题 (HTTP COLLECT) 相同,因为您需要使用 http.get()。但是,这次您将获得三个 URL 作为前三个命令行参数。

您必须收集每个 URL 提供给您的完整内容,并将其打印到控制台 (stdout)。您不需要打印出长度,只需打印出字符串形式的数据即可;每个 URL 一行。问题是您必须按照与作为命令提供给您的 URL 相同的顺序打印它们行参数。”

我尝试使用 node.js stream.readable 类将响应从第一个 URL 传输到第二个 URL,然后将响应从该 URL 传输到第三个。我原以为这会同步运行,即当第一个请求完成时,第二个请求将通过管道传输。我正在使用包 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 调用的第一个数据,第一个单词丢失了。

{I think it's becoz of using multiple pipes on the same data for first 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]);
}
}

关于javascript - node.js 流管道异步或同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26297404/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com