nic*_*ick 3 asynchronous http response node.js
我对 Node http 模块非常熟悉,并且遇到了一些麻烦。
这里的最终目标是获取一个巨大的 URL 列表,找出哪些是有效的,然后抓取这些页面以获取某些数据。因此,第一步是确定 URL 是否有效,这个简单的练习让我感到困惑。
假设我们有一个数组 allURLs:
["www.yahoo.com", "www.stackoverflow.com", "www.sdfhksdjfksjdhg.net"]
Run Code Online (Sandbox Code Playgroud)
目标是迭代这个数组,向每个数组发出一个 get 请求,如果有响应,则将链接添加到工作 URL 列表(现在只是另一个数组),否则它会转到损坏的 URL 列表。
var workingURLs = [];
var brokenURLs = [];
for (var i = 0; i < allURLs.length; i++) {
var url = allURLs[i];
var req = http.get(url, function (res) {
if (res) {
workingURLs.push(?????); // How to derive URL from response?
}
});
req.on('error', function (e) {
brokenURLs.push(e.host);
});
}
Run Code Online (Sandbox Code Playgroud)
我不知道的是如何正确地从请求/响应对象本身获取 url,或者真正如何构建这种异步代码 - 因为再说一次,我是一个 Nodejs 磨砂:(
对于大多数网站来说,使用 res.headers.location 是可行的,但有时标头没有此属性,这会在以后给我带来问题。我还尝试过控制台记录响应对象本身,这是一个混乱且徒劳的努力
我尝试将 url 变量推送到工作 URL,但是当任何响应返回时触发推送时,for 循环已经结束,并且 url 永远指向 allURLs 数组的最后一个元素。
感谢任何能提供帮助的人
您需要关闭 url 值才能访问它并保护它免受下一次循环迭代的更改。
例如:
(function(url){
// use url here
})(allUrls[i]);
Run Code Online (Sandbox Code Playgroud)
最简单的解决方案是使用forEach而不是for.
allURLs.forEach(function(url){
//....
});
Run Code Online (Sandbox Code Playgroud)
承诺的解决方案可以让您在工作完成时得到一刻:
var http = require('http');
var allURLs = [
"http://www.yahoo.com/",
"http://www.stackoverflow.com/",
"http://www.sdfhksdjfksjdhg.net/"
];
var workingURLs = [];
var brokenURLs = [];
var promises = allURLs.map(url => validateUrl(url)
.then(res => (res?workingURLs:brokenURLs).push(url)));
Promise.all(promises).then(() => {
console.log(workingURLs, brokenURLs);
});
// ----
function validateUrl(url) {
return new Promise((ok, fail) => {
http.get(url, res => return ok(res.statusCode == 200))
.on('error', e => ok(false));
});
}
// Prevent nodejs from exit, don't need if any server listen.
var t = setTimeout(() => { console.log('Time is over'); }, 1000).ref();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
883 次 |
| 最近记录: |