【问题标题】:Using returning value in callback在回调中使用返回值
【发布时间】:2014-12-12 06:20:15
【问题描述】:

在来自 Angularjs Docs 的 this example 中有一些 *magic*,我无法弄清楚。 这是一个代码:

var User = $resource('/user/:userId', {userId:'@id'});
var user = User.get({userId:123}, function() {
  user.abc = true;
  user.$save();
});

还有一件事让我感到困惑——当需要首先填充 user 时,我们如何在回调中引用 user 对象并获取检索到的数据。但要这样做,应该从 User.get() 返回值。

这样:

调用User.get() → 从User.get()返回 → 调用function() 回调

但是return之后就什么都不能执行了吧?

【问题讨论】:

  • 这里没有魔法,用户由 get 调用填充,回调稍后发生 - 用户可以通过闭包范围在回调中访问。
  • 你是对的,但你知道 User.get 会返回什么吗?对我来说似乎是一个对象。如果是这样的话,当回调被执行时将获得 abc 属性。可以在代码的任何位置故意调用回调..
  • @Guillermo。用户确实似乎是一个对象。当回调发生时,它要么改变值,要么创建用户对象的 abc 属性。
  • Really Grisha - 要理解这段代码,您必须阅读异步编码和 JavaScript 闭包范围。作为一个曾经是 C# 开发人员的人,这有点奇怪,但你会掌握它的窍门。

标签: javascript angularjs


【解决方案1】:

绝对有可能返回用户并且仍然没有执行回调,这就是这个代码示例所展示的。

User.get 的实现可能是这样的:

User.prototype.get = function(parameters, callback) {
  var user = {
     abc: false
  }

  // do other stuff to construct the object

  someLongAsyncOperation(callback);

  return user;
}

这里返回了用户,但是还有一个回调要完成。然后在该回调中,可以通过闭包范围访问用户。 someLongAsyncOperation 可以是以后调用回调的任何东西,你可以自己尝试一下,比如 setTimeout 或 Angular 的 $timeout。

在我看来这不是一个很好的模式,最好将创建的用户作为参数包含在回调中 - 但它会起作用。

【讨论】:

  • 谢谢。没想到回调函数可以传到别的地方再调用,User.get()的生存时间!=回调引用的生存时间。
  • 但是在这里我们遇到了promise,因为User.get() 应该很快终止,即在一些网络事件上注册。但是不可能获得对 user 对象本身的引用,并且 User.get() 返回“转换”对象,我猜是的。
【解决方案2】:
  1. User.get() 返回一个空白对象并对/user/123 执行异步 GET。这个空对象被赋值给函数作用域中的user变量。
  2. 函数的其余部分(如果有的话)执行并且函数返回。
  3. 当异步调用返回时,get() 方法使用返回对象的属性填充现有空白对象的属性,因此user 变量现在具有回调的结果。
  4. get() 方法调用您指定的回调。它可以访问函数的 user 变量,该变量现在从异步调用中填充。

【讨论】:

    猜你喜欢
    • 2016-09-18
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多