2010-11-04 159 views
0

我有以下一段JavaScript,但对于某些范围的原因,从myfunc返回的“名称”为空。JavaScript范围问题

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

如何让它突破范围?

回答

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); }); 
+0

我怎么能这样做? – 2010-11-04 21:15:53

+0

我会添加到我的答案。 – Pointy 2010-11-04 21:44:29

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

尝试使名称的全局

+1

这不会帮助,我不认为。 *最终*“名字”数组将被填充,但不是立即。 – Pointy 2010-11-04 18:18:55

1

如果client.query(...)是异步的,那么selectCb功能不会运行,不会因时间已改变, myfunc返回。您需要重新设计myfunc以异步返回名称(例如,通过接受它在selectCb末尾调用的函数参数)。

+0

您能否给我一个具体的例子或者指点我一些参考?谢谢! – 2010-11-04 21:16:23