簡體   English   中英

使異步調用同步

[英]Make asynchronous calls synchronous

我曾經用PHP構建Web應用程序,因此習慣了同步執行操作。

我目前正在嘗試構建網絡抓取工具。 它的工作方式是

  1. 代理列表
  2. 檢查代理是否有效
  3. 使用代理刮取Web內容。

但是,我已經意識到大多數調用都是同步的,並且我很難理解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

async.each為每個項目並行執行迭代器。

使用async.eachSeries進行同步調用。

您可以嘗試promise,創建promise以獲取代理,然后執行promise檢查它。

您可以在這里找到更多關於諾言的信息

例:

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;
    });
}

這樣,您就創建了一個獲得代理列表的承諾。 同樣,您可以執行此操作以檢查代理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM