2015-09-25 258 views
0

我曾经在PHP中构建web应用程序,因此习惯于同步执行任务。使异步调用同步

我目前正试图建立一个网页刮板。它的工作方式是代理

  1. 抢列表
  2. 检查代理正在使用代理
  3. 刮网页内容。

但是,我意识到大部分调用是同步的,我很难理解nodejs中的异步模块。

这是主要的方法。

var proxyChecker = require('proxy-checker'); 
var request = require('request'); 
var forEach = require('async-foreach').forEach; 
var async = require('async'); 

var proxiesJar = []; 
var goodProxies = []; 
var proxyCount = 0;  
parseProxiesList(function(error) { 
     async.each(proxiesJar, checker, function(err, result) { 
      console.log('Result:' + err); 
     }); 
    }); 

获取代理列表

function parseProxiesList(callback) { 
    console.log("parseProxiesList"); 
    request('http://hidden.com', function (error, response, body) { 
     if (error) { 
      console.log("Error [1]"); 
      return callback(error); 
     } 
     console.log("Got proxies list"); 
     if (!error && response.statusCode == 200) { 
      proxies = body.split(/\r?\n/); 
      var shouldBreak = false; 

      for (var i = 0; i < proxies.length; i++) { 
       if (/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:[0-9]{1,5}/.test(proxies[i])) { 
        p = proxies[i].split(' '); 
        var elts = p[0].split(':'); 
        var host = elts[0]; 
        var port = elts[1]; 
        proxiesJar.push(host + ":" + port); 
       } 
      } 
      callback(null, 1); 
     } 
    }); 
} 

获取代理列表后,它会检查代理工作。

var checker = function(proxy, callback) { 
    var p = proxy.split(':'); 
    var host = p[0]; 
    var port = p[1]; 
    console.log('[Checking] ' + host + ':' + port); 
    proxyChecker.checkProxy(host, port, {url: 'http://google.com',regex: /Google/}, function(host, port, ok, statusCode, err) { 

     if(!ok) { 
      console.log("Proxy don't work: " + host + ":" + port); 
      return callback(err); 
     } else { 
      console.log("Working proxy: " + host + ":" + port); 
      goodProxies.push(host + ":" + port); 
      return callback(null, host + ":" + port); 
     } 
    }); 
}; 

日志,然而,结果是,而不是

[Checking] 1.1.1.1:80 
[Checking] 2.2.2.2:80 
. 
. 
. 
Working proxy: 1.1.1.1:80 
Working proxy: 2.2.2.2:80 

[Checking] 1.1.1.1:80 
Working proxy: 1.1.1.1:80 

[Checking] 2.2.2.2:80 
Working proxy: 2.2.2.2:80 
+0

我认为你的标题是倒退。你的代码已经是异步的。整个问题已经混合起来了。 –

+0

@KevinB对不起,修正。对这两个术语感到非常困惑。 – MrYanDao

+0

通常不可能使异步代码同步,除非有一个同步执行的单独方法,例如,readFile vs readFileSync。但是,您可以使代码以串行方式执行,这是彼得的答案如下。 –

回答

1

async.each执行迭代器用于并行每个项目。对于同步呼叫,使用async.eachSeries

0

你可以尝试承诺,创建一个承诺,获得一个代理,然后执行一个承诺来检查它。

你可以找到更多的承诺在here

例子:

function parseProxiesList() { 
    var deferred = Q.defer() 
    console.log("parseProxiesList"); 
    request('http://hidden.com', function (error, response, body) { 
     if (error) { 
      console.log("Error [1]"); 
      deferred.reject(error); 
     } 
     console.log("Got proxies list"); 
     if (!error && response.statusCode == 200) { 
      proxies = body.split(/\r?\n/); 
      var shouldBreak = false; 

      for (var i = 0; i < proxies.length; i++) { 
       if (/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:[0-9]{1,5}/.test(proxies[i])) { 
        p = proxies[i].split(' '); 
        var elts = p[0].split(':'); 
        var host = elts[0]; 
        var port = elts[1]; 
        proxiesJar.push(host + ":" + port); 
       } 
      } 
      deffered.resolve(proxiesJar); 
     } 
     return deffered.promise; 
    }); 
} 

你已经创建了一个承诺,让代理列表这样。同样,你可以做检查代理。