【发布时间】:2014-11-26 15:08:21
【问题描述】:
我一直在 learnyounode 的帮助下学习 nodejs,但我被困在 Juggling Async 上。我的解决方案适用于问题中最困难的部分——它会乱序打印结果,因为某些请求先于其他请求完成。我试图在不使用任何帮助库的情况下做到这一点,所以我点击了谷歌。我找到了一个关于控制流的很棒的教程 - http://book.mixu.net/node/ch7.html 但发现他的系列解决方案 - 一个异步 for 循环只能正常工作,因为他的异步函数在返回之前正好等待 1000 毫秒。在我的示例中,时间是可变的,因此您不会以相同的顺序获得结果。然后该示例开始构建一个控制流库,我觉得虽然它可以工作,但它超出了 learnyounode 分配的范围。
我尝试过的一些事情是:
创建一个包含 URL、订单和响应数据的对象。我遇到的问题是,当我坐在 http.get 的回调中时,我不知道我正在获取数据的 URL。这实际上是我尝试过的大多数事情的错误,我不知道如何将我得到的数据链接到回调中的特定 URL。
使用 asyncCounter 作为索引在存储数组中专门设置一个位置 foe 返回的数据。因此,当事件“结束”发生时,我会按照您在下面的代码中看到的那样设置它。显然这不起作用,因为呼叫在不同的时间结束。
最终,我屈服并研究了解决方案。这是我所拥有的,我用星号标记了我的解决方案中缺少的内容。
var http = require("http");
var storage = [];
var urlList = [];
var asyncCounter = 0;
//Store all the URL's from the command line in an array
for(var i = 2; i < process.argv.length; i++){
urlList.push(process.argv[i]);
}
//This function prints out all the data in the storage array
//The storage array contains the data received from http.get
function AsyncComplete(){
for(var j = 0; j < storage.length; j++){
console.log(storage[j]);
};
};
//Entry function
function main(){
//Do an http get on each of the provided URL's
for(var i = 0; i < urlList.length; i++){
**(function(i){**
http.get(urlList[i], function(response){
var body = "";
//Got a chunk of data!
response.on("data", function(chunk){
body += chunk;
});
//All done with our request.
response.on("end", function (){
//Store the total response from the URL
storage[**i**] = body;
asyncCounter++;
//Check if we can print the results yet
//I want to wait for all the calls to complete so I am using a counter
if(asyncCounter == urlList.length){
AsyncComplete();
}
});
});
**})(i);**
};
};
main();
所以我再次访问 Google,因为我不知道他们在做什么,我发现了一种叫做闭包的东西。根据我的理解,他们所做的让 i 在回调的范围内 - 我无法弄清楚如何做到这一点,认为这是不可能的并且很早就被放弃了。
我的问题是这究竟是如何工作的——特别是为什么他们有 (i) 他们在哪里工作以及它的用途是什么。没有那个 (i),解决方案就无法工作。为什么你可以把 (function(i){ 扔到某个地方?这是我一百万年来从未想过要做的事情。
我找到了https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures,它似乎可以包含答案,所以我将在此期间通读它,看看我是否能想出一些东西。
提前感谢您的宝贵时间!
史蒂夫。
【问题讨论】:
标签: javascript node.js asynchronous closures