Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/443.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript CoffeeScript函数返回函数而不是值_Javascript_Google Chrome Extension_Coffeescript_Google Chrome Devtools_Firebase - Fatal编程技术网

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+),所以删除基数是安全的。