Javascript CoffeeScript函数返回函数而不是值
我有一个散列,它调用一个函数来获取一个值。问题是,函数返回的是内部函数,而不是它应该返回的值 (用户是在此哈希上定义的) 我的哈希:Javascript CoffeeScript函数返回函数而不是值,javascript,google-chrome-extension,coffeescript,google-chrome-devtools,firebase,Javascript,Google Chrome Extension,Coffeescript,Google Chrome Devtools,Firebase,我有一个散列,它调用一个函数来获取一个值。问题是,函数返回的是内部函数,而不是它应该返回的值 (用户是在此哈希上定义的) 我的哈希: userInfo = { id: user.id, email: user.email, cars: getCars(user.id), } 它调用此函数: getCars = (userId) -> id = parseInt(userId) userRef = new Fi
userInfo = {
id: user.id,
email: user.email,
cars: getCars(user.id),
}
它调用此函数:
getCars = (userId) ->
id = parseInt(userId)
userRef = new Firebase("https://demo-firebase.firebaseIO.com/users/#{id}/")
userRef.on('value', (snapshot) ->
if snapshot.val() == null
["toyota"]
else
snapshot.val().cars # returns an array of cars
)
当我在调试器中单步执行该函数时,它会在行的userRef.上返回,而不是在if/else
语句中的正确位置返回
以下是编译后的JS:
getCars = function(userId) {
var id, userRef;
id = parseInt(userId);
userRef = new Firebase("https://demo-firebase.firebaseIO.com/users/" + id + "/");
return userRef.on('value', function(snapshot) {
if (snapshot.val() === null) {
return ["toyota"];
} else {
return snapshot.val().cars;
}
});
};
知道为什么会这样吗?我肯定我忽略了一些简单的东西。因此,您从firebase获得的数据是事件驱动的和异步的,所以您不能像返回同步代码一样返回它。您需要使用回调、承诺或事件处理程序
getCars = (userId, callback) ->
id = parseInt(userId)
userRef = new Firebase("https://demo-firebase.firebaseIO.com/users/#{id}/")
userRef.on 'value', (snapshot) ->
if snapshot.val() == null
callback ["toyota"]
else
callback snapshot.val().cars # returns an array of cars
userInfo =
id: user.id
email: user.email
getCars user.id, (cars) ->
userInfo.cars = cars
#Don't user userInfo until here as it's not ready/populated yet!
(注意节点约定是回调(errornull,value)
,但为了简单起见,这里省略了错误处理)
还要注意的是,几乎所有不熟悉异步javascript的人都会犯这个错误,但这并不是一个简单的语法问题,这是一个基本问题,在某个时候(也许今天),你会有一个大好时机。要做的事情是在chrome调试器中逐步完成这一过程,并注意每行代码执行的顺序与时间的关系。带有if
语句的行在getCars
返回之后执行。请注意,如果您单步执行它,它将跳过'value'
事件处理程序的正文,因为该行只定义了事件处理程序,但在数据到达之前它不会实际执行它,因此如果您希望在其中进行调试,则需要在该函数的第一行设置断点(其中,if
语句为)
有3种常见的范例可供使用:事件绑定、承诺和回调。所有这些都会起作用。为每个范例编写相同的功能代码,并了解它们基本上都为您提供了一种方法,让您等待一些数据到达,然后运行一些代码以响应数据到达。谢谢接下来,我将在BIT中发布任何后续问题。我知道,if
语句会在稍后执行。此外,这不是一个节点应用程序,如果这很重要的话。在使用user.id(cars)的第三行到最后一行调用getCars
时,我不太清楚您的语法->
。这对meSo来说似乎很奇怪,这意味着调用getCars
函数,传递2个参数-user.id
作为参数1,函数(回调)作为参数2。回调是一个定义在那里的匿名函数。啊,我只是被语法弄糊涂了。我通常以getCars(userId,cars)的形式编写东西
但我猜在这种情况下应该是getCars(userId,(cars)->userInfo.cars=cars)
,对吗?完全正确。我省略了函数参数周围的参数,因为这样做可以很容易地将函数作为最后一个参数传递,而不必在文件的更深处使用结束参数。调用时确实应该指定基数:id=parseInt(userId,10)
@muistooshort现代浏览器不再将前导零视为八进制。因为已知目标平台是正常的(Chrome扩展意味着Chrome/Opera 15+),所以删除基数是安全的。