Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 可变范围。用闭包?_Javascript_Ajax_Scope_Closures - Fatal编程技术网

Javascript 可变范围。用闭包?

Javascript 可变范围。用闭包?,javascript,ajax,scope,closures,Javascript,Ajax,Scope,Closures,我正在尝试抓取我的Facebook照片的所有URL。 我首先加载带有唱片id的“albums”数组。 然后我循环浏览相册并加载带有照片URL的“图片”数组。 (我在Chrome的JS调试器中看到了这一点) 但当代码到达最后一条语句(“返回图片”)时,“图片”为空 我该如何解决这个问题? 我觉得我应该使用闭包,但不完全确定如何最好地完成它。 谢谢 你在按程序思考你的问题。但是,只要处理异步请求,此逻辑就会失败。我想你最初尝试的是这样的: var pictures = getMyPhotos();

我正在尝试抓取我的Facebook照片的所有URL。 我首先加载带有唱片id的“albums”数组。 然后我循环浏览相册并加载带有照片URL的“图片”数组。 (我在Chrome的JS调试器中看到了这一点)

但当代码到达最后一条语句(“返回图片”)时,“图片”为空

我该如何解决这个问题? 我觉得我应该使用闭包,但不完全确定如何最好地完成它。 谢谢


你在按程序思考你的问题。但是,只要处理异步请求,此逻辑就会失败。我想你最初尝试的是这样的:

var pictures = getMyPhotos();
for (var i = 0; i < pictures.length; i++) {
    // do something with each picture
}
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);

现在,您可以在任何需要的地方使用全局变量“pictures”(或显式使用window.pictures)。当然,问题是您必须首先调用getMyPhotos,然后等待响应完成,然后才能使用它们。不需要本地存储。

如评论中所述,异步代码就像加州酒店一样——您可以随时查看,但您永远不能离开

您是否注意到
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();

问题不在于可变范围,而是ajax调用是异步的(也应该是异步的)。自SO诞生以来,每天都有人以这样或那样的方式一次又一次地问这个问题。排序答案是您不能/不应该
从外部函数返回任何内容。如果有更多依赖于
图片的代码,请在
FB.api
回调中使用回调。我需要返回一个包含所有相册中所有照片的数组。在第二个嵌套的FB.api调用中的回调中如何执行此操作?我必须等到整个“pictures”数组填满后才能返回。@JMan您不能在回调中返回值,因为没有人可以返回它(记住,对getMyPhotos的调用已经退出)。您可以使用回调通知对“嘿,这是您请求的数据”感兴趣的人,就像我说的:您不能
返回
图片
数组。如果有依赖于填充的代码,则需要在
FB.api
回调中执行。谢谢,Matt,我理解。但是我的其余代码偶尔需要访问这些照片,所以所有这些都需要嵌套在getMyPhotos()中?有没有办法摆脱这种筑巢的混乱?我正在考虑编写HTML5 localStorage的照片链接,以便其他代码稍后可以引用。@JMan更新了我的答案。很多人都避免将数据放在全局名称空间中,但我想说,在JS开发阶段,这是一个可以接受的折衷方案(更不用说比localStorage更容易)。localStorage带来的一个好处是,您不必在每次加载页面时调用getMyPhotos,而是从localStorage获取它
getMyPhotos(function(pictures){
var pictures = getMyPhotos();