JavaScript范围问题

时间:2010-11-04 18:11:20

标签: javascript scope

我有以下一段javascript但是由于某些范围的原因,从myfunc返回的“名称”是空的。

var myfunc = function(client, id) {
  var names = new Array();
  client.query(
    'SELECT stuff FROM mytable WHERE id="'+id+'"',
    (function selectCb(err, results, fields) {
      if (err) {
        throw err;
      }
      for (result in results) {
        // This prints fine
        console.log(results[result].name);
        names[result] = results[result].name;
      }
      client.end();
    })
  );
  // The following returns empty
  return names;
}

console.log(myfunc(1,2));

如何让它超出范围?

3 个答案:

答案 0 :(得分:1)

如果 client.query(...)是异步的,则 selectCb 功能将无法运行且名称不会更改当 myfunc 返回时。您需要重新设计 myfunc 以异步方式返回名称(例如,接受在 selectCb 末尾调用的函数参数)。

答案 1 :(得分:1)

它是空的,因为对“查询”功能的调用是异步。在结果可用之前,您传递的功能将不会运行。因此,在调用回调函数之前很久就会立即返回“myfunc”函数。

在浏览器中使用Javascript,您必须考虑这些术语。不要期望你的“名字”立即就绪,而是改变“myfunc”,以便你传递一个回调函数,当名字实际可用时调用它:

var myfunc = function(client, id, whenFinished) {
  var names = new Array();
  client.query(
    'SELECT stuff FROM mytable WHERE id="'+id+'"',
    (function selectCb(err, results, fields) {
      if (err) {
        throw err;
      }
      for (result in results) {
        // This prints fine
        console.log(results[result].name);
        names[result] = results[result].name;
      }
      client.end();
      if (whenFinished) whenFinished(names); // callback
     })
  );
};

现在当你调用你的函数时,你将传递另一个函数而不是期望“名字”作为返回值:

myfunc(1, 2, function(names) { console.log(names); });

答案 2 :(得分:0)

var names = new Array();

var myfunc = function(client, id) {

  client.query(
    'SELECT stuff FROM mytable WHERE id="'+id+'"',function selectCb(err, results, fields)
  {
      if (err) {
        throw err;
      }
      for (result in results) {
        // This prints fine
        console.log(results[result].name);
        names[result] = results[result].name;
      }
      client.end();
    }
  );
  // The following returns empty
  return names;
}

console.log(myfunc(1,2));

尝试将名称设为全球