JavaScript范围问题

JavaScript范围问题,javascript,scope,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) {

我有下面的一段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));
我怎样才能使它超出范围

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

如果client.query(…)是异步的,那么selectCb函数将不会运行,name也不会在myfunc返回时更改。您需要重新设计myfunc以异步返回名称(例如,接受它在selectCb末尾调用的函数参数)。

它是空的,因为对“查询”函数的调用是异步的。在结果可用之前,传递给它的函数不会运行。因此,您的“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
     })
  );
};
现在,当您调用函数时,不要期望“names”作为返回值,而是传入另一个函数,该函数将作用于名称列表:

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

我认为那没用。最终会填充“names”数组,但不会立即填充。你能给我一个具体的例子或给我一些参考吗?谢谢