async.each不会运行回调

时间:2016-05-17 16:44:49

标签: node.js

我试图异步调用一些URL并收集结果。我已经用#34; Promises"完成了它。现在我试图绕过async.js。

这是一段剪辑代码:

var request = require("request"),
    cheerio = require("cheerio");
    // base_url = "http://de.indeed.com/Jobs?q=";  // after equal sign for instance:   sinatra&l=
var async = require('async');

/* search syntax:
   - http://de.indeed.com/Jobs?q=node&l=berlin&radius=100
*/

var search_words = ["django", "python", "flask",
                    "rails", "ruby",
                    "node", "javascript", "angularjs", "react", "express", "meteor",
                    "java", "grails", "groovy",
                    "php", "symfony", "laravel" ];


var base_url = "http://de.indeed.com/Jobs?q=";
var stats = [];


async.each(search_words, function(keyword)  {
    var url = base_url + keyword + "&l=";
    request( base_url + keyword + "&l=", function(err, resp, body) {
        if (err) throw err;
        $ = cheerio.load(body);
        num_str = $("#searchCount")[0].children[0].data.split(" ").reverse()[0];
        num_str = num_str.replace(/\./, "");
        num_str = num_str.replace(/,/, "");

        stats.push( [keyword, num_str] );
    });
}, function(err) {
    if (err) throw err;
    console.log(stats);
});

根据this,我可以将回调函数作为async.each的最后一个参数传递,一旦数组被处理就会触发。

在我的情况下,回调似乎永远不会被触发。

Btw:Trevor Burnham在他的书中提到了#34; Async Javascript"函数asyn.forEach似乎已从async.js中删除了它?

@robertklep给了我一个提示,给iteratee函数添加一个回调。 //这是工作版本:

var request = require("request"),
    cheerio = require("cheerio");
    // base_url = "http://de.indeed.com/Jobs?q=";  // after equal sign for instance:   sinatra&l=
var async = require('async');

/* search syntax:
   - http://de.indeed.com/Jobs?q=node&l=berlin&radius=100
*/

var search_words = ["django", "python", "flask",
                    "rails", "ruby",
                    "node", "javascript", "angularjs", "react", "express", "meteor",
                    "java", "grails", "groovy",
                    "php", "symfony", "laravel" ];


var base_url = "http://de.indeed.com/Jobs?q=";
var stats = [];

async.each(search_words, function(keyword, callback)  {
    var url = base_url + keyword + "&l=";
    request( url, function(err, resp, body) {
        if (err) {
            callback("ERROR in request");
        } else {
            $ = cheerio.load(body);
            num_str = $("#searchCount")[0].children[0].data.split(" ").reverse()[0];
            num_str = num_str.replace(/\./, "");
            num_str = num_str.replace(/,/, "");
            num = parseInt(num_str);

            stats.push( [keyword, num] );
            callback();
        }
    });
}, function(err) {
    if(err) {
        console.log(err);
    } else {
        stats_sorted = stats.sort( function(a, b) {
            return b[1] - a[1];
        });
        console.log(stats_sorted);
    }
});

2 个答案:

答案 0 :(得分:0)

你错过了iteratee获得两个参数的部分:项目一个回调。当iteratee完成时(或发生错误时)需要调用此回调:

async.each(search_words, function(keyword, callback)  {
  var url = base_url + keyword + "&l=";
  request( base_url + keyword + "&l=", function(err, resp, body) {
      if (err) return callback(err);

      $ = cheerio.load(body);
      num_str = $("#searchCount")[0].children[0].data.split(" ").reverse()[0];
      num_str = num_str.replace(/\./, "");
      num_str = num_str.replace(/,/, "");

      stats.push( [keyword, num_str] );

      return callback();
  });
}, function(err) {
  if (err) throw err;
  console.log(stats);
});

鉴于您要将每个search_words映射到一个值,您应该考虑使用async.map()。这样,您就不会需要单独的stats数组。

.each().forEach()曾经是同义词,但在最近的版本中,.forEach()已被删除。

答案 1 :(得分:0)

非常确定一旦从请求

返回响应,您需要在回调中传回结果
request( base_url + keyword + "&l=", function(err, resp, body) {
        if (err) throw err;
        $ = cheerio.load(body);
        num_str = $("#searchCount")[0].children[0].data.split(" ").reverse()[0];
        num_str = num_str.replace(/\./, "");
        num_str = num_str.replace(/,/, "");

        stats.push( [keyword, num_str] );
    });