我正试图抓住我Facebook照片的所有网址。 我首先加载带有专辑ID的“专辑”数组。 然后我遍历相册并加载带有照片网址的“图片”数组。 (我在Chrome的JS调试器中看到了这一点。)
但是当代码到达最后一个语句(“返回图片”)时,“图片”为空。
我该如何解决这个问题? 我觉得我应该使用一个闭包,但不完全确定如何做到这一点。 感谢。
function getMyPhotos() {
FB.api('/me/albums', function(response) {
var data = response.data;
var albums = [];
var link;
var pictures = [];
// get selected albums id's
$.each(data, function(key, value) {
if ((value.name == 'Wall Photos')) {
albums.push(value.id);
}
});
console.log('albums');
console.log(albums);
// get the photos from those albums
$.each(albums, function(key, value) {
FB.api('/' + value + '/photos', function(resp) {
$.each(resp.data, function(k, val) {
link = val.images[3].source;
pictures.push(link);
});
});
});
console.log('pictures');
console.log(pictures);
return pictures;
});
}
答案 0 :(得分:3)
你在程序上考虑你的问题。但是,只要您处理异步请求,此逻辑就会失败。我希望你最初尝试做的事情看起来像这样:
var pictures = getMyPhotos();
for (var i = 0; i < pictures.length; i++) {
// do something with each picture
}
但是,这不起作用,因为'pictures'的值实际上是未定义的(这是没有定义实际返回的任何函数的默认返回类型 - 这是你的getMyPhotos所做的)
相反,你想做这样的事情:
function getMyPhotos(callback) {
FB.api('/me/albums', function (response) {
// process respose data to get a list of pictures, as you have already
// shown in your example
// instead of 'returning' pictures,
// we just call the method that should handle the result
callback(pictures);
});
}
// This is the function that actually does the work with your pictures
function oncePhotosReceived(pictures){
for (var i = 0; i < pictures.length; i++) {
// do something with each picture
}
};
// Request the picture data, and give it oncePhotosReceived as a callback.
// This basically lets you say 'hey, once I get my data back, call this function'
getMyPhotos(oncePhotosReceived);
我强烈建议你围绕SO搜索有关AJAX回调和异步JavaScript编程的更多问题/答案。
编辑:
如果要将FB api调用的结果保存到其他代码中,可以在窗口中将返回值设置为'global'变量:
function getMyPhotos(callback) {
FB.api('/me/albums', function (response) {
// process respose data to get a list of pictures, as you have already
// shown in your example
// instead of 'returning' pictures,
// we just call the method that should handle the result
window.pictures = pictures;
});
}
您现在可以在任何地方使用全局变量'pictures'(或明确使用window.pictures)。当然,问题在于您必须先调用getMyPhotos,然后等待响应完成后才能使用。不需要localStorage。
答案 1 :(得分:0)
正如评论中所提到的,异步代码就像加利福尼亚酒店 - 你可以随时查看,但你永远不能离开。
您是否注意到FB.api
未返回值
//This is NOT how it works:
var result = FB.api('me/albums')
但是接收一个延续函数并将其结果传递给它?
FB.api('me/albums', function(result){
事实证明你需要对你的getMyPhotos功能有类似的安排:
function getMyPhotos(onPhotos){
//fetches the photos and calls onPhotos with the
// result when done
FB.api('my/pictures', function(response){
var pictures = //yada yada
onPhotos(pictures);
});
}
当然,延续传递风格具有传染性,因此您现在需要调用
getMyPhotos(function(pictures){
而不是
var pictures = getMyPhotos();