如何使learnyounode#9杂耍asynchronous工作

我正在尝试通过nodechool的learnyounode。

这个问题和前面的问题(HTTP COLLECT)是一样的,你需要使用http.get()。 但是,这次您将获得三个URL作为前三个命令行参数。

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

这是我的代码:

var bl = require('bl'); var http = require('http'); var urls = [process.argv[2], process.argv[3], process.argv[4]] var dataArray = []; var count = 0; for (var i = 0; i <= urls.length-1; i++) { http.get(urls[i], function(response){ response.setEncoding('utf8').pipe(bl(function (err, data) { dataArray[i] = data.toString(); count++; if (count==2){ dataArray.forEach(function(item){ console.log(item); }) } })); }); }; 

当我尝试validation它时:

  1. 实际上:“她会是牛奶吧,就像牛奶吧一样平平,给我们一个斗兽也是疯狂的。
  2. 期待:“让我们得到一些帕尔马的警惕,她会是正确的砖块,没有担心,他有一个巨大的cookies,让我们得到一些gobful flamin,她会是正确的丁字裤。

  3. 实际:“”

  4. 期待:“让你的狗生病吧,他有一个巨大的stream浪汉,像一个十字架一样stream血。”

  5. 实际:

  6. 期待:“她会是正确的女配angular,就像牛奶吧一样,抓住我们的牙膏也是疯狂的战斗。

  7. 实际:

  8. 预期:“”

我在这里做错了什么?

你想检查,如果count == 3因为你有3个url。

你也不想在这样的循环中使用一个函数。 在这种情况下,每次执行匿名函数时, i值为3 …这就是为什么您只输出第三个url的期望值。

这是一个很好的例子: 循环中的JavaScript闭包 – 简单实用的例子

通过将函数包装成一个新的函数,你可以确保i正是你想要的。

这应该工作:

 var bl = require('bl'); var http = require('http'); var urls = [process.argv[2], process.argv[3], process.argv[4]]; var dataArray = []; var count = 0; function juggle (i) { http.get(urls[i], function(response) { response.setEncoding('utf8').pipe(bl(function(err, data) { dataArray[i] = data.toString(); count++; if (count == 3) { dataArray.forEach(function(item) { console.log(item); }); } })); }); } for (var i = 0; i < 3; i++) { juggle(i) } 

你写的脚本结束了在命令行上传入的最后一个参数。

在debugging中使用节点4.2.4我跑了:

 node debug test.js google.com facebook.com yahoo.com 

c继续。

repl在debugging时访问上下文。

s进入一个function。

循环每次以“yahoo.com”结束。

For循环是使用节点进行asynchronous操作的,正如在复制链接中所build议的那样,您需要在i计数器上bind或创build一个闭包。 但是,如何改变循环的迭代:

 var bl = require('bl'); var http = require('http'); var urls = [process.argv[2], process.argv[3], process.argv[4]] var dataArray = []; var count = 0; urls.forEach(function(url, i){ console.log(url) var options = { hostname: url, port: 80 } http.get(options, function(response){ console.log(options, response.statusCode) response.setEncoding('utf8').pipe(bl(function (err, data) { dataArray[i] = data.toString(); count++; console.log(options, data) })); }) .on('error', function(e) { console.log("Got error: " + e.message); }); }) 

结果:

 < google.com < facebook.com < yahoo.com < { hostname: 'google.com', port: 80 } 301 < { hostname: 'google.com', port: 80 } <Buffer 3c 48 54 4d 4c 3e 3c 48 45 41 44 3e 3c 6d 65 74 61 20 68 74 74 70 2d 65 71 75 69 76 3d 22 63 6f 6e 74 65 6e 74 2d 74 79 70 65 22 20 63 6f 6e 74 65 6e ... > < { hostname: 'yahoo.com', port: 80 } 301 < { hostname: 'yahoo.com', port: 80 } <Buffer 3c 48 54 4d 4c 3e 0a 3c 48 45 41 44 3e 0a 3c 54 49 54 4c 45 3e 45 72 72 6f 72 3c 2f 54 49 54 4c 45 3e 0a 3c 2f 48 45 41 44 3e 0a 0a 3c 42 4f 44 59 20 ... > < { hostname: 'facebook.com', port: 80 } 302 < { hostname: 'facebook.com', port: 80 } <Buffer > 

注意我添加了options因为不包含“http://”作为URL的一部分我得到:

 < google.com < facebook.com < yahoo.com < Got error: connect ECONNREFUSED 127.0.0.1:80 < Got error: connect ECONNREFUSED 127.0.0.1:80 < Got error: connect ECONNREFUSED 127.0.0.1:80 

请注意:

  • JavaScript,Node.js:是Array.forEachasynchronous?
  • 以及如何绑定或创build闭包: 在JavaScript for循环内的asynchronous过程

或者使用承诺:

 var bl = require('bl'); var http = require('http'); var urls = [process.argv[2], process.argv[3], process.argv[4]] var dataArray = []; var count = 0; for (var i = 0; i <= urls.length-1; i++) { console.log(i) // Or you can use a promise which will create a closure with // the callback passed in // uncomment this promise to see the difference // Promise.resolve(i).then(function(i){ console.log(i, urls) http.get({hostname: urls[i], port:80}, function(response){ response.setEncoding('utf8').pipe(bl(function (err, data) { dataArray[i] = data.toString(); count++; console.log(urls[i], i, data) })); }).on('error', function(e){ console.log(e.message) }); // }); }; 

没有承诺:

 < 0 < 0 [ 'http://google.com', < 'http://facebook.com', < 'http://yahoo.com' ] < 1 < 1 [ 'http://google.com', < 'http://facebook.com', < 'http://yahoo.com' ] < 2 < 2 [ 'http://google.com', < 'http://facebook.com', < 'http://yahoo.com' ] < undefined 3 <Buffer 3c 68 74 6d 6c 3e 0d 0a 3c 68 65 61 64 3e 3c 74 69 74 6c 65 3e 34 30 30 20 42 61 64 20 52 65 71 75 65 73 74 3c 2f 74 69 74 6c 65 3e 3c 2f 68 65 61 64 ... > < undefined 3 <Buffer 3c 68 74 6d 6c 3e 0d 0a 3c 68 65 61 64 3e 3c 74 69 74 6c 65 3e 34 30 30 20 42 61 64 20 52 65 71 75 65 73 74 3c 2f 74 69 74 6c 65 3e 3c 2f 68 65 61 64 ... > < undefined 3 <Buffer 3c 68 74 6d 6c 3e 0d 0a 3c 68 65 61 64 3e 3c 74 69 74 6c 65 3e 34 30 30 20 42 61 64 20 52 65 71 75 65 73 74 3c 2f 74 69 74 6c 65 3e 3c 2f 68 65 61 64 ... > 

承诺:

 < 0 < 1 < 2 < 0 [ 'http://google.com', < 'http://facebook.com', < 'http://yahoo.com' ] < 1 [ 'http://google.com', < 'http://facebook.com', < 'http://yahoo.com' ] < 2 [ 'http://google.com', < 'http://facebook.com', < 'http://yahoo.com' ] < http://google.com 0 <Buffer 3c 68 74 6d 6c 3e 0d 0a 3c 68 65 61 64 3e 3c 74 69 74 6c 65 3e 34 30 30 20 42 61 64 20 52 65 71 75 65 73 74 3c 2f 74 69 74 6c 65 3e 3c 2f 68 65 61 64 ... > < http://facebook.com 1 <Buffer 3c 68 74 6d 6c 3e 0d 0a 3c 68 65 61 64 3e 3c 74 69 74 6c 65 3e 34 30 30 20 42 61 64 20 52 65 71 75 65 73 74 3c 2f 74 69 74 6c 65 3e 3c 2f 68 65 61 64 ... > < http://yahoo.com 2 <Buffer 3c 68 74 6d 6c 3e 0d 0a 3c 68 65 61 64 3e 3c 74 69 74 6c 65 3e 34 30 30 20 42 61 64 20 52 65 71 75 65 73 74 3c 2f 74 69 74 6c 65 3e 3c 2f 68 65 61 64 ... >