很确定已经有人问过,但我不知道该搜索什么。无论如何,
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。
我正在检查(完全向下滚动):this并且他的代码运行正常。那我的代码出了什么问题?我只是想避免递归,如果可能的话。
答案 0 :(得分: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.length
放入expecting
,以防万一您在函数运行时使用livemarkIds
执行其他操作。如果不是,您可以直接使用它。
重新评论以下内容:
然而,系统的工作原理如下:我在一个数组中获得了livemark。这个代码实际上是在一个类(和方法)中,所以另一个类初始化这个代码并调用函数getFeeds(),它将返回该实况标记数组。
如果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
回调中调用回调。等等。
一旦你习惯了它,它就很容易做到。习惯它可能会很棘手。 : - )