while(count!== 3)无法检查回调状态 [英] while(count!==3) fail to check callback state

查看:69
本文介绍了while(count!== 3)无法检查回调状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过 NodeSchool 中的一个名为learningyounode的教程来学习Node。这大约是它提供的13个问题之一:将3个http get请求发送到前3个命令行参数指示的3个url,在收集所有响应块后,按url的顺序打印响应。

我想出了以下代码片段:

I was learning Node with a tutorial called learnyounode from NodeSchool. This is about one of the 13 questions it provided: send 3 http get requests to 3 urls indicated by first 3 command line arguments, print out the responses in the order of urls when all the response chunks are collected.
I came up with this code snippet:

var http = require("http");
var count = 0;
var strArr = ["","",""];
getData(0);
getData(1);
getData(2);
while(count!==3);
console.log(strArr[0]);
console.log(strArr[1]);
console.log(strArr[2]);

function getData(i) {
    http.get(process.argv[i+2], function (response) {
        response.setEncoding("utf8");
        response.on("data", function (data) {
            strArr[i] += data;
        });
        response.on("end", function (data) {
            count++;
        });
    });
}

我期望while循环会阻止打印语句我直到计数变成3为止,也就是说,所有3个响应都被完全收集。但是,它没有按我预期的那样工作。另外,我在while循环中放置了一条print语句,它表明count始终为0。

然后我偷看了答案,了解到一种解决方法是检查回调中count的值 response.on( end,...),如下所示:

I was expecting the while loop to hold back the print statements for me until count turns 3, that is, all 3 responses are gathered completely. However, it didn't work as I expected. Also, I put a print statement in the while loop and it showed that count would always be 0.
I then peeked the answer and learned that a way around is to check the value of count in the callback for response.on("end", ...), like below:

var http = require("http");
var count = 0;
var strArr = ["","",""];
getData(0);
getData(1);
getData(2);

function getData(i) {
    http.get(process.argv[i+2], function (response) {
        response.setEncoding("utf8");
        response.on("data", function (data) {
            strArr[i] += data;
        });
        response.on("end", function (data) {
            count++;
            if(count===3) {
                console.log(strArr[0]);
                console.log(strArr[1]);
                console.log(strArr[2]);
            }
        });
    });
}

这样,我确实通过了测试,但是为什么循环方法无法解决仍然令我困惑。

预先感谢任何关注此方法的人。

This way, I did pass the test, but why the while-loop method didn't work out still puzzles me.
Thanks in advance for anyone who looks at this.

推荐答案

JavaScript是单线程的。它会执行每个执行上下文,直到完成为止,然后检查事件循环,以查看是否有排队等待执行的新执行上下文(例如异步函数的回调)。

JavaScript is single-threaded. It executes each execution context until it is finished, then it checks with the event loop to see if there are any new execution contexts queued up that it should execute (such as the callback of an asynchronous function).

三个 getData 调用均立即返回,然后在线程中执行while循环。 http.get 的回调在当前执行上下文完成之前无法执行(直到while循环及其执行后的所有操作),因此无法增加计数

The three getData calls all return immediately, then the while loop executes in the thread. The callbacks to http.get cannot execute until the current execution context is finished (until the while loop and everything after it have executed), so there is no way for count to increase, and no way for the loop to end.

找到的解决方案效果很好,但是为了帮助理解您应该意识到setTimeout和setInterval是异步的,因此它们不要阻塞线程。您可以使用以下方法解决此问题:

The solution you have found works well, but to help with understanding you should realize that setTimeout and setInterval are asynchronous, so they do not block the thread. You could have solved this with something like:

getData(0);
getData(1);
getData(2);

setTimeout( function check_count ( ) { 
    if ( count !== 3 )
        return setTimeout( check_count, 100 );

    console.log(strArr[0]);
    console.log(strArr[1]);
    console.log(strArr[2]);

}, 100 );

这不是一个很好的解决方案,因为它每100 ms进行一次检查,而不是等到第三个执行回调,然后立即记录结果。这只是在不阻塞线程的情况下如何循环的演示。

That's not a nice solution, since it is arbitrarily checking every 100 ms instead of just waiting until the third callback executes and then immediately logging the results. It is just a demonstatrion of how you can "loop" without blocking the thread.

这篇关于while(count!== 3)无法检查回调状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆