0

很确定这已经被问过了,但我不知道要搜索什么。反正,

var livemarks = [];

var livemarkIds = PlacesUtils.annotations.getItemsWithAnnotation("livemark/feedURI", {});

for (var i = 0; i < livemarkIds.length; i++){

    PlacesUtils.livemarks.getLivemark( {id : livemarkIds[i]}, function(result, livemark){

        if (result == Components.results.NS_OK){
            livemarks.push(livemark);
        }

    });

}

alert(livemarks.length);

我正在尝试使用不再由其创建者维护的 Firefox 插件,只是为了学习一点。我最近收到一条错误消息,说 getFeedURI 将被弃用,我想更改他的旧功能。

编辑:

从函数(内部函数)中定义的函数,我无法访问父级中定义的 var。为什么?例如,我无法从 getLivemark() 或其他类似的内部函数中访问 var livemarks。

我正在检查(完全向下滚动):和他的代码工作正常。那么我的代码有什么问题?如果可能的话,我只是想避免递归。

4

1 回答 1

6

我怀疑该PlacesUtils.livemarks.getLivemark函数以异步方式完成其工作,因此您提醒length. 将警报放入回调中,您应该会看到正确的长度(最终)。这是一种方法:

var expecting = livemarkIds.length;
for (var i = 0; i < livemarkIds.length; i++){

    PlacesUtils.livemarks.getLivemark( {id : livemarkIds[i]}, function(result, livemark){

        if (result == Components.results.NS_OK){
            livemarks.push(livemark);

            // ***New stuff***
            if (livemarks.length === expecting) {
                // Now you have them all, now you can do the next thing
                doSomethingWithTheLiveMarks(livemarks);
            }
        }

    });
}

请注意,我放在那里livemarkIds.lengthexpecting以防您livemarkIds在函数运行时执行其他操作。如果你不是,你可以直接使用它。


在下面回复您的评论:

然而,系统的工作原理是这样的:我在一个数组中获得了 livemarks。这段代码实际上是在一个类(和方法)中,所以另一个类初始化这个并调用函数 getFeeds(),它将返回那个 livemarks 数组。

如果PlacesUtils.livemarks.getLivemark是异步的,则不可能getFeeds将数组作为返回值返回。例如,它不能像这样使用:

a = b;
c = 42;
feeds = getFeeds(feedIds);
if (feeds.length === 0) {
    // Do something
}
else {
    // Do something else
}

好消息是它真的很容易修复:getFeeds接受一个回调函数,当它有提要时调用它。上面的代码更改为如下所示:

a = b;
c = 42;
feeds = getFeeds(feedIds, function(feeds) {
    if (feeds.length === 0) {
        // Do something
    }
    else {
        // Do something else
    }
});

如您所见,这是一个非常简单的更改。假设上面的循环是所有getFeeds,那么getFeeds最终看起来像这样:

function getFeeds(livemarkIds, callback) {

    var livemarks = [];
    for (var i = 0; i < livemarkIds.length; i++){

        PlacesUtils.livemarks.getLivemark( {id : livemarkIds[i]}, function(result, livemark){

            if (result == Components.results.NS_OK){
                livemarks.push(livemark);

                if (livemarks.length === livemarkIds.length) {
                    // Done, trigger the callback
                    callback(livemarks);
                }
            }

        });
    }
}

并且模式继续:如果代码调用getFeeds被其他期望异步返回值的东西调用,而不是返回该值,您让代码接受回调,并从回调中调用getFeeds回调。等等。

一旦你习惯了它,这很容易做到。习惯它可能会很棘手。:-)

于 2012-06-21T17:37:25.230 回答