NodeJS:在上一个函数返回之前继续的函数

时间:2014-12-19 18:27:27

标签: node.js

我开始使用带有脚本的NodeJS(而不是webapp),这让我感到困惑。我有以下简化的功能:

var request = require('request');

function first_func(name) {
  console.log('first_func(' + name + ')');
  var url = 'http://...' + name;
  var answers = new Array();  
  request(url, function(error, resp, html) {
    ...
    answers.push(x);
  });
  return answers;
}

function second_func(answers) {
  var results = new Array();
  for (var a in answers) {
    var url = 'http://...' + a;
    request(url, function(error, resp, html) {
      ...
      results.push(x);
    });
  }
  return results;
}

first_func()废弃目录页面,second_func()废弃该条目的特定页面。该脚本在脚本末尾以这样的方式运行:

var names = ['a', 'b', ...];

function main() {
  for (var n in names) {
    var ans = first_func(names[n]);
    console.log('answers: ' + ans);
    for (var a in ans) {
      second_func(ans[a]);
    }
  }
}

main();

出于某种原因,NodeJS并行执行first_func()second_func()。在运行first_func()之前,为什么不等second_func()完成?输出是:

  

答案:未定义

     

first_func(a)中

     

first_func(b)中

     

...

为什么在等待for返回之前,NodeJS会跳进main()中的内部first_func()循环?

1 个答案:

答案 0 :(得分:1)

您可以使用async module解决此问题。它看起来像下面这样:

var request = require('request');
var async = require('async');

function first_func(name, done) {
  console.log('first_func(' + name + ')');
  var url = 'http://...' + name;
  request(url, function(error, resp, html) {
    ...
    done(answers);
  });
}

function second_func(answers, done) {
  var results = new Array();
  async.each(answers, function(answer, next) {
    var url = 'http://...' + a;
    request(url, function(error, resp, html) {
      ...
      results.push(x);
      next();
    });
  }, function(err) {
    done(results);
  });
}

var names = ['a', 'b', ...];

function main() {
  async.each(names, function(name, next) {
    first_func(name, function(err, answers) {
      second_func(answers, function(results) {
        // do something wit results
        next();
      });
    });
  }, function(err) {
    // done will everything
  });  
}

main();

当你完成获取所需的值而不是返回它们时,你基本上会调用一个函数。异步模块将允许您以异步友好的方式迭代数组。