1

在将处理后的信息发送回客户端之前,我的 Node.js 应用程序会在服务器端发出两种类型的 http 请求:

  • 第一种服务器端请求从外部 API 获取链接列表(只有一个请求);
  • 第二种服务器端请求获取网页的 html(重复 10 次,因为 API 返回的列表包含 10 个 URL)。

即使我看到请求了 10 个 URL,也只生成了 8 个响应。这是代码:

app.get('/search', function(clientReq, clientRes) {
    console.log(clientReq.query.r);
    // first type of request to retrieve the json data containing 10 URLs
    var searchReq = https.request({ host: 'myhost.com', path: '/?q=' + clientReq.query.r }, function(searchRes) {
        console.log('searching...');
        var searchOutput = '';
        var communications = [];
        var waiting = 0;

        searchRes.on('data', function(d) {
            searchOutput += d;
        });

        searchRes.on('end', function() {
            var obj = JSON.parse(searchOutput);
            for(var i = 0; i < obj.results.length; i++){
                waiting++;
                console.log(encodeURIComponent(obj.results[i].uniqueId)); // prints 10 URLs
                // second type of request, fetches a web page listed in searchOutput
                var fetchReq = https.request({ host: 'myhost.com', path: '/?uniqueId='+ encodeURIComponent(obj.results[i].uniqueId) }, function(fetchRes) {
                    var htmlOutput = '';
                    console.log("starting to read the fetch response"); // only logs 8 times
                    fetchRes.on('data', function(d) {
                        htmlOutput += d;
                        if (htmlOutput.toString().indexOf("<div>") !== -1) {
                            var communication = "";
                            var $ = cheerio.load(htmlOutput.toString().substring(htmlOutput.toString().indexOf("<body "),htmlOutput.toString().indexOf("<div>")));
                            $('p').each(function (index) {
                                communication += $(this).text();
                            });
                            communications.push({"x":communication});
                            fetchRes.destroy();
                            waiting--;
                            complete();
                        }
                    });
                    fetchRes.on('end', function() {
                        console.log('this is the end of the fetch response'); // only logs 8 times
                    });   

                    fetchRes.on('error', function(e) {
                        console.error(e);
                    });
                });
                fetchReq.end(console.log("fetchReq ended")); // prints 10 times
                fetchReq.on('error', function(e) {
                    console.error(e);
                });  
            };    
            function complete() {
                if(waiting === 0) {
                    clientRes.send(communications);
                }
            }
        });
    });

    searchReq.end();

    searchReq.on('error', function(e) {
        console.error(e);
    });
});

我使用fetchRes.destroy();的 HTML 可能很大,我只需要它的顶部。

这是我控制台中的输出,从第 10 个开始fetchReq ended

fetchReq ended
starting to read the fetch response
this is the end of the fetch response
starting to read the fetch response
this is the end of the fetch response
starting to read the fetch response
this is the end of the fetch response
starting to read the fetch response
this is the end of the fetch response
starting to read the fetch response
this is the end of the fetch response
starting to read the fetch response
this is the end of the fetch response
starting to read the fetch response
this is the end of the fetch response
starting to read the fetch response
this is the end of the fetch response

如您所见,我只收到了 8 个回复。最终结果是communications永远不会发送回浏览器,因为waiting没有到达0

4

0 回答 0