CoffeeScript函数返回的是函数而不是值

CoffeeScript function returning a function and not a value

本文关键字:函数 返回 CoffeeScript      更新时间:2023-09-26

我有一个散列,它调用一个函数来获取值。问题是,函数返回的是函数内部的值,而不是它应该返回的值。

(用户定义在此散列之上)

我的散列:

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.on行返回,而不是在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获得的数据是事件驱动的异步数据,因此您不能将其当作同步代码来返回。您需要使用回调、promise或事件处理程序。

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!

(注意,节点约定是callback(errorOrNull, value),但为了简单起见,我在这里省略了错误处理)

还要注意的是,几乎每个新接触异步javascript的人都会犯这个错误,但这不是一个简单的语法问题,这是一件基本的事情——在某个时候(也许今天),你会有一个顿悟的时刻。要做的事情是在chrome调试器中逐步完成这一过程,并注意每行代码执行的顺序时间的关系。带有if语句的行在getCars已经返回之后执行LATER IN TIME。请注意,如果您遍历它,它将直接跳过'value'事件处理程序的主体,因为这一行只是定义事件处理程序,但在数据到达之前,它实际上不会执行它,所以如果您想在其中进行调试,则需要在该函数的第一行(if语句所在的位置)设置断点。

有三种常见的范例可用于此:事件绑定、承诺和回调。一切都会好起来的。对你来说,用每种范式来编码同样的功能是一个很好的练习,并理解它们基本上都为你提供了一种等待一些数据到达,然后运行一些代码来响应数据到达的方式。