Javascript LearnyYouNode#9杂耍异步

Javascript LearnyYouNode#9杂耍异步,javascript,node.js,Javascript,Node.js,我正试图通过诺德学校的学习中心 此问题与中的上一个问题(HTTP收集)相同 您需要使用http.get()。然而,这一次你将 提供了三个URL作为前三个命令行参数 您必须收集每个用户提供给您的完整内容 URL并将其打印到控制台(stdout)。你不需要打印出来 长度,只是数据作为字符串;每个URL一行。问题是 您必须以与URL相同的顺序打印它们 作为命令行参数提供给您 我很困惑为什么我的解决方案不能完全工作,因为它看起来和我一样,但功能更强大,并且不确定它们的内部测试工作: 1. ACTUAL

我正试图通过诺德学校的学习中心

此问题与中的上一个问题(HTTP收集)相同 您需要使用http.get()。然而,这一次你将 提供了三个URL作为前三个命令行参数

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

我很困惑为什么我的解决方案不能完全工作,因为它看起来和我一样,但功能更强大,并且不确定它们的内部测试工作:

1.  ACTUAL:    ""
1.  EXPECTED:  "As busy as a dead horse also lets get some dero. Built like a sleepout no dramas lets get some chook. She'll be right thingo my she'll be right ute. "

2.  ACTUAL:    "She'll be right bizzo no worries she'll be right fair dinkum. We're going aerial pingpong no worries as busy as a gyno. "
2.  EXPECTED:  "She'll be right bizzo no worries she'll be right fair dinkum. We're going aerial pingpong no worries as busy as a gyno. "

3.  ACTUAL:    "He's got a massive pretty spiffy heaps she'll be right brizzie. He hasn't got a fly wire where shazza got us some strewth. She'll be right spit the dummy with it'll be fair go. We're going gobsmacked with as stands out like arvo. He's got a massive bush bash mate she'll be right slacker. "
3.  EXPECTED:  "He's got a massive pretty spiffy heaps she'll be right brizzie. He hasn't got a fly wire where shazza got us some strewth. She'll be right spit the dummy with it'll be fair go. We're going gobsmacked with as stands out like arvo. He's got a massive bush bash mate she'll be right slacker. "

4.  ACTUAL:    ""
4.  EXPECTED:  ""
我的代码:

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

var result = [];
var urls = process.argv.slice(2);
urls.forEach(function(url, i) {
  http.get(url, function(response) {
    response.pipe(bl(function(err, data) {
      if (err) return console.error(err);
      result[i] = data.toString();
      if (i === urls.length - 1) {
        console.log(result.join('\n'));
      }
    }));
  });
});
官方解决方案:

var http = require('http')
var bl = require('bl')
var results = []
var count = 0

function printResults () {
  for (var i = 0; i < 3; i++)
    console.log(results[i])
}

function httpGet (index) {
  http.get(process.argv[2 + index], function (response) {
    response.pipe(bl(function (err, data) {
      if (err)
        return console.error(err)

      results[index] = data.toString()
      count++

      if (count == 3)
        printResults()
    }))
  })
}

for (var i = 0; i < 3; i++)
  httpGet(i)
var http=require('http'))
var bl=需要('bl')
var结果=[]
变量计数=0
函数printResults(){
对于(变量i=0;i<3;i++)
console.log(结果[i])
}
函数httpGet(索引){
http.get(process.argv[2+索引]、函数(响应){
响应管道(bl)(功能(错误、数据){
如果(错误)
返回控制台。错误(err)
结果[索引]=data.toString()
计数++
如果(计数=3)
打印结果()
}))
})
}
对于(变量i=0;i<3;i++)
httpGet(一)

基本上,第一个测试永远不会通过(尽管如果迭代数组中只有1个url(而不是3个),那么第一个测试通过,而其他测试则不会通过)。任何洞察都会很好。我不知道在哪里可以问这个问题,也许我只是错过了一些JS的东西,如果这不合适,那么很抱歉。

您还没有确保所有URL都已下载

请求不一定按顺序返回。想想看,如果3先回来。您将跳过其他两个URL,只打印3个


演示代码统计响应的数量,因此它保证在打印答案之前获得所有信息。

我认为您只需等待所有请求的结果结束或出现任何一个错误。我的答案如下:

var http = require('http');

var links = [2, 3, 4];

var buffer = [];

(function render(index) {

http.get(process.argv[links[index]], function (response){

    response.setEncoding('utf8');

    response.on('data', function(chunk){
        if(buffer[index] === undefined) {
            buffer[index] = '';
        }
        buffer[index] += chunk;
    });
    response.on('end', function () {
        var newIndex = index+1;
        if(links[newIndex] !== undefined) {
            render(newIndex);
        } else {
            return renderOutput();
        }
    });
    response.on('error', console.error);

}).on('error', console.error);
})(0); //self-calling function

function renderOutput() {

buffer.forEach(function (elem) {

console.log(elem);

});
}
var http = require('http');
var bl = require('bl');

var urls = process.argv.slice(2)
var count = urls.length;

var results = [];

urls.forEach((url, index) => {
    http.get(url, (res) => {
        res.pipe(bl((err, data) => {
            if (err) throw err;

            results[index] = data.toString();
            count--;

            if (count == 0) {
                results.forEach((result) => {
                    console.log(result)
                });
            }
        }))
    })
})

我在没有使用bufferList(bl)模块的情况下实现了它,这可能是一种更通用的方法

        var http = require('http');
        var urlList = [];
        urlList.push(process.argv[2]);
        urlList.push(process.argv[3]);
        urlList.push(process.argv[4]);
        var results = []
        var count = 0

        function getURLdata (index) {
            http.get(urlList[index], function(response){
                var data = {};
                data[index] = '';      
                response.setEncoding('utf-8');
                response.on('error', function(err){
                    console.log(err);
                });
                response.on('data', function(chunk){
                    data[index] += chunk;
                });


                response.on('end', function(){
                    results[index] = data;
                    count++;
                    if (count == urlList.length){
                        for (var i = 0; i < urlList.length; i++){
                            console.log(results[i][i]);
                        } 
                    }
                });

            });
        }

        for (var i = 0; i < urlList.length; i++)
            getURLdata(i);
var http=require('http');
var urlist=[];
push(process.argv[2]);
push(process.argv[3]);
push(process.argv[4]);
var结果=[]
变量计数=0
函数getURLdata(索引){
get(urlList[index],函数(响应){
变量数据={};
数据[索引]='';
响应。设置编码('utf-8');
响应.on('error',函数(err){
控制台日志(err);
});
响应.on('data',函数(块){
数据[索引]+=块;
});
on('end',function(){
结果[指标]=数据;
计数++;
if(count==urlist.length){
对于(var i=0;i
我是一个初学者,所以这个解决方案可能有问题,这是使用async/await,通过做出一系列承诺并等待它们解决,这将控制响应的顺序

const axios = require("axios")
const  getURL = async url =>
{
  let res = await axios.get(url)
  return res.data
}

const getUrlArray = () => 
{
  let args = process.argv.slice(2)
  .map(e => getURL(e))
  return Promise.all(args)
}

getUrlArray()
.then(data => data.forEach(e => console.log(e)))

非常简单的解决方案,但可以完成任务:

const http = require('http');
const bl = require('bl');
var x; 

for (x = 2; x < 5; x++) {
  http.get(process.argv[x], function (res) {
    res.pipe(bl(function (err, data) {
      if (err) { return console.error(err) }
      console.log(data.toString());
    }));
  });
};
consthttp=require('http');
常数bl=要求('bl');
var x;
对于(x=2;x<5;x++){
http.get(process.argv[x],函数(res){
资源管道(bl)(功能(错误、数据){
if(err){return console.error(err)}
log(data.toString());
}));
});
};

当您异步下载时,您也尝试异步打印它们。只有当您知道下载完成后,才应该打印。正如@mrmcgreg所指出的,演示代码等待计数达到3,然后决定打印结果。它们所做的最大区别在于,它们仅在将
数据
分配给结果后才增加计数。谢谢!我错过了这一点,我全神贯注于在我的arr中以正确的顺序获得响应,而没有考虑它们是否完成下载。我将我的console.log编辑为
if(result.filter(function(res){return res!==undefined;}).length==url.length{//log所有URL返回响应时的结果console.log(result.join('\n'));}
,尽管经过再三考虑,使用int进行计数可能更好:)