【问题标题】:Recursive Asynchronous Callbacks in JavascriptJavascript中的递归异步回调
【发布时间】:2013-02-28 14:32:50
【问题描述】:

关于this question,我正在尝试添加回调以取回数据。所以我尝试了这个:

var subgroupIds = [];
var that = this;
this.getSubGroups = function (groupId,callback) {
    var anotherObject = this;
    this.getGroups("groupId="+groupId, function(groups) {
        if ($.isEmptyObject(groups)) {
            return;
        } else {
            $.each(groups, function(index,group) {
                subgroupIds.push(group.id);
                that.getSubGroups(group.id);
            });
            anotherObject.callback(group.id);
        }
     });
}

我认为在上一个问题之后我对闭包有了更好的理解,但我想我没有......我收到以下错误:

Uncaught TypeError: Object [object Window] has no method 'callback'

我在这里做错了什么?

编辑

getGroups 的内容如下:

this.getGroups = function(filter,callback,error_callback) {
    this.getJSON('/'+apiVersion+'/groups/',function(data){
        // run through the filter engine
        output = runFilter(data, filter);
        callback(output);
    },error_callback);
}

【问题讨论】:

  • 也许this.getGroups 应该是anotherObject.getGroups
  • 你为什么用anotherObject而不是that?还有为什么要回调一个属性,不就是要回调函数参数吗?
  • 什么是this/that?当你声明this.getSubGroups 时,this 指的是window,所以你没有做正确的事情来让this 指代正确的事情。然后,anotherObject 只是指同一个,window。另外,你为什么要使用anotherObject.callback(group.id)?你不想要callback(group.id);吗?
  • 我没有看到任何递归,顺便说一句。
  • @beri 'that.getSubGroups(group.id);'是递归的

标签: javascript recursion callback closures


【解决方案1】:

不需要anotherObject.callback(group.id);,你需要的是callback(group.id);

您似乎将 thisarguments 对象混淆了。

arguments 保存所有传入函数的参数:

var aFunction = function () {
    for (var i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
};

aFunction(1, 2, 3, 4); // 1, 2, 3, 4

虽然this 基本上是指函数的“所有者”(粗略地说,就是点之前的任何内容):

var aFunction = function () {
    console.log(this);
};

var object1 = { f: aFunction, name: "object1" };
var object2 = { f: aFunction, name: "object2" };

object1.f(); // Object { name="object1", f=function()}
object2.f(); // Object { name="object2", f=function()}
aFunction(); // Window

【讨论】:

  • 认为我明白你在说什么。我以为我收到了错误,因为callbackgetSubGroups 的一个参数,而getGroupscallback 不可见,因为它是另一个级别。我尝试将anotherObject.callback(group.id); 更改为callback(group.id);,但出现此错误:Uncaught TypeError: undefined is not a function
  • @PLui 那是因为你递归调用that.getSubGroups(group.id); - 你没有提供第二个参数 - 回调 - 这就是为什么它是undefined。您要么必须在每次调用函数时提供回调,要么引入检查:if (callback) { callback(group.id); }
  • 如果您希望在每个递归调用中调用相同的回调,您只需传递它:that.getSubGroups(group.id, callback);
  • 啊,这让我更接近了。我现在注意到的是,如果我有一个包含祖父母、父母和孩子的组结构,则此函数的递归性质本质上将调用 getSubGroups 三次(每个级别)。这会导致callback 被调用两次。我真的只想要最后一个subgroupIds,因为它给了我完整的子组列表。我该如何解决?
  • 我认为我的逻辑有缺陷。我不应该返回一个数组。相反,也许我应该在找到子组时使用callback(group.id)。谢谢或帮助 Nikita!
【解决方案2】:

回调是一个参数,它不绑定到上下文。

我想你想要的是用anotherObject 作为this 值来调用回调,对吧?

您可以通过以下方式实现:

$.proxy(callback, anotherObject)(group.id);

或者如果你只想执行回调,而你想使用闭包,你需要添加:

this.callback = callback; //before
var anotherObject = this;

【讨论】:

  • 你的意思是callback.call(anotherobject, group.id)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
  • 2019-03-10
  • 2018-02-24
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多