我无法调用已命名的回调函数

时间:2014-12-31 14:06:29

标签: javascript node.js callback

我很难搞清楚如何创建一个函数并从另一个函数调用它作为回调。我的下面的代码已被剔除进行故障排除,但我试图尽可能多地命名我的功能以使其更清洁。通过取消命名函数并使它们全部匿名内联,我取得了一些成功。

我特别对函数定义括号内的变量声明感到困惑。

function pickRnd (err, res, pullQuestions) {
      var i = 0;
      var qSelects = new Array(); 
      qSelects.k1 = Math.floor(Math.random() * res.n);
      qSelects.k2 = Math.floor(Math.random() * res.n);
      while ( qSelects.k2 == qSelects.k1 ) {
        qSelects.k2 = Math.floor(Math.random() * res.n);
        i++;
        if (i == 20) {break;}
      }
      qSelects.k3 = Math.floor(Math.random() * res.n);
      while ( qSelects.k3 == qSelects.k2 || qSelects.k3 == qSelects.k1 ) {
        qSelects.k3 = Math.floor(Math.random() * res.n);
        i++;
        if (i == 40) {break;}
      }
      console.log('::' + qSelects.k1);
      console.log('::' + qSelects.k2);
      console.log('::' + qSelects.k3);

      function pullQuestions(qSelects) {
        console.log('function pullQuestions start');
        var qArray = new Object();
        db.records.findOne({}).skip(qSelects.k1, function(err, result) {
          qArray.push(result);
        });
        db.records.findOne({}).skip(qSelects.k2, function(err, result) {
          qArray.push(result);
        });
        db.records.findOne({}).skip(qSelects.k3, function(err, result) {
          qArray.push(result);
        });
        console.log('2' + qArray);
      };
    }

module.exports = function(res) {
  console.log(res);
  db.records.runCommand('count', function (err, res) {
    console.log(res);
    console.log(res.n);
    pickRnd(null, res);
  });
}

1 个答案:

答案 0 :(得分:2)

您已向pickRnd宣布第三个参数,并将其称为pullQuestions。但是在您的pickRnd正文中,您还宣布了一个名为pullQuestions的函数。

当你致电pickRnd时,你并没有传递三个参数,这表明你不想在pickRnd参数列表中列出第三个参数。

但您实际上pullQuestions函数中的任何地方调用 pickRnd,因此在那里声明它是没有意义的。


  

我特别对函数定义括号内的变量声明感到困惑。

那些不是变量,尽管它们与变量相似。他们是参数。它们是函数在被调用时期望从其调用者那里得到的东西。更简单的例子:

function foo(a) {
    console.log("a = " + a);
}

foo期望在你打电话时收到一个参数。 foo将使用名称a引用该参数。所以在这次电话会议中:

foo(42);

...在foo代码中,a将为42

相反,变量通常是函数内部的。例如:

function foo(a) {
    var b;
    b = a * 2;
    console.log("a = " + a);
    console.log("b = " + b);
}

现在,foo期望收到一个参数,它调用a,并且单独foo声明它将在内部使用的局部变量b


关于调用命名函数和/或回调,或许另一个简单的例子会有所帮助:假设我们有foofoo将调用我们传递给它的回调函数:

function foo(count, callback) {
    var n;
    for (n = 0; n < count; ++n) {
        callback(n);
    }
}

如果我们致电foo,它会调用我们给它count次的回调,其号码从0开始,每次增加1。所以这里有一个匿名函数作为回调:

foo(5, function(x) {
    console.log(x);
});

&#13;
&#13;
function foo(count, callback) {
  var n;
  for (n = 0; n < count; ++n) {
    callback(n);
  }
}

foo(5, function(x) {
  snippet.log(x);
});
&#13;
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
&#13;
&#13;

这是一个命名函数bar的示例,作为回调:

function bar(x) {
    console.log(x);
}

foo(5, bar);

&#13;
&#13;
function foo(count, callback) {
  var n;
  for (n = 0; n < count; ++n) {
    callback(n);
  }
}

function bar(x) {
  snippet.log(x);
}

foo(5, bar);
&#13;
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
&#13;
&#13;