当前位置: 首页 > 面试题库 >

异步请求后数组中的未定义索引

艾修然
2023-03-14
问题内容

我在一个数组上遇到了一些困难,该数组(在异步调用之外)定义得很好,但是当我在一个异步请求(例如$
.getJSON)中调用其索引时,该数组的所有索引都未定义,但是 长度 是还是一样。这是我的代码

我指的数组是 friendsArray

该数组在第二个“ $
.getJSON”调用期间具有正确的索引,但是在该函数的回调内部,其所有索引都变为未定义。由于数组是在方法范围内定义的,因此不应该保留其值吗?

if (response.status === 'connected') { 
var accessToken = $.trim(response.authResponse.accessToken);
var hashArray = [];
var friendArray = [];
document.getElementById("statusCheck").innerHTML = accessToken;
$.getJSON('https://graph.facebook.com/me/friends?access_token=' + accessToken, 
  function(dataJSON){
    hashArray = dataJSON['data'];
    for (var i = 0; i < hashArray.length; i++){
        friendArray.push(hashArray[i]["id"]);
    }
    var resultJSON = "{";
    var resultArray = [];

    for (var i = 0; i < friendArray.length; i++){
        $.getJSON('https://graph.facebook.com/me/mutualfriends/' + 
                  friendArray[i] + "?access_token=" + accessToken, 
            function(dataJSON2){
                resultArray = dataJSON2['data'];
                resultJSON += friendArray[i] + ":" + resultArray.length + ",";
                //alert(resultJSON);
            })
        if (i == friendArray.length - 1){
            postArrayPopulation(resultJSON);
        }
    }

});

}


问题答案:

问题在于,ajax函数完成后,回调函数会在一段时间后发生。届时,数组索引将前进到for循环的末尾(因此它指向数组的末尾)为未定义的值。该数组仍然存在,但是在调用完成函数时,索引已更改。

通常,将索引获取到成功处理程序中的技术是在函数闭包中捕获该索引,在该闭包中捕获该索引以供完成函数使用。

您可以使用以下内容替换成功处理程序,从而创建一个捕获索引值的闭包:

(function(index) {
    return function(dataJSON2) {
        resultArray = dataJSON2['data'];
        resultJSON += friendArray[index] + ":" + resultArray.length + ",";
        //alert(resultJSON);
    }
}) (i);

该外部函数执行并创建一个闭包,该闭包捕获i的值,并使它唯一可用于成功处理程序。当自身执行时,它将返回成功处理程序,该处理程序随后将传递给getJSON函数,以供稍后调用。但是,稍后调用它时,所需的值i可通过自执行函数中的参数提供给成功处理程序。

这是考虑与回调一起使用的闭包的另一种方法。

  1. 任何函数在声明时都可以访问作用域内的所有变量,即使在父作用域中处于较高级别的变量也可以访问,即使该函数后来被称为回调。这实际上是许多其他语言所没有的javascript的巨大功能。
  2. 因此,如果我们希望变量在以后执行回调时可供回调函数使用,我们只需要以某种方式使该变量进入该回调函数的范围即可。

这是一个例子:

function cycleOnOff(sel, cnt, delay) {
    var obj = $(sel);

    function next() {
        if (cnt-- > 0) {
            obj.toggle();
            setTimeout(next, delay);
        }
    }
    next();
}

在这种情况下,该功能next()是一个回调setTimeout(),但该功能已完全进入到其父范围内的变量:selcntdelayobj

  1. 如果变量在初始设置回调和调用回调之间没有变化,则非常简单。您可以只使用匿名函数声明,并且在稍后调用回调时,在定义匿名函数时可用的所有更高范围的变量仍将可用。
  2. 如果变量确实随着代码继续执行而发生更改,并且您想提供一个特定的值,则该变量现在在以后被调用时可供回调使用-这是在棘手的情况下。一个人所能做的就是创建一个函数,将这个变量传递给它,从而创建一个范围,使该变量具有所需的值,并且在该范围内不会随着其他代码的继续执行而改变。但是,因为我们要的是回调函数,而不仅仅是函数调用,所以我们必须以半古怪的方式将两者结合起来。我们进行函数调用并将其传递给所需的值。在该函数调用中,我们返回对回调函数的引用。这会适当地分配回调函数,但是会将回调函数放入一个捕获所需变量值的闭包中。更好的是 这个闭包对于该回调的特定实例是唯一的,因此对回调的每次使用都将拥有它自己的闭包,因此它是该变量的唯一值。我们为您的特定问题创建的关闭/回调就是一个例子。


 类似资料:
  • 我真的需要温习一下我的异步等待和promise。我想要一些建议。 我正在对firebase firestore进行异步函数调用。函数应根据单个输入参数返回字符串。 该功能适用于1-1用户聊天。该功能是创建聊天/查找现有聊天,并返回其ID。 现在,我得到的作为返回值的和不知道为什么。除了返回之外,该函数还能正常工作。 我有两个功能。一个是React类组件生命周期方法,另一个是我的firebase异步

  • 我希望我的请求触发一些长时间运行的操作,这些操作应该在后台执行。我编写了以下实现,应该在后台处理我的操作,但实际上我的请求是同步执行的: 在日志中,我看到以下内容: 我看到我的在另一个线程中执行,但出于某种原因,我的原始请求等待sleep完成 更新1:

  • 我尝试了拉雷维尔的入门指南。通用域名格式。 有一章创建了任务。回调和函数

  • 问题内容: 我正在用PHP执行两个curl请求。它们的外观如下: 他们正在工作,但有时第二个curl post请求未执行。 我想同时执行这两个请求。 我怎样才能做到这一点?请注意,他们在邮递区中采取不同的选择。 谢谢你的帮助! 问题答案: 因此,您要做的是异步执行cUrl请求。 因此,您将需要一个用于php的异步/并行处理库。 php的著名线程库之一是 您首先需要获取dll / so文件并将其保存

  • 问题内容: 我尝试了python 请求库文档中提供的示例。 使用,我得到了响应代码,但是我想获得所请求的每个页面的内容。例如,这不起作用: 问题答案: 注意 下面的答案是不适用于请求v0.13.0 +。编写此问题后,异步功能已移至。但是,你可以将其替换为下面的内容,它应该可以工作。 我已经留下了这个答案,以反映原始问题,即有关使用请求的问题。 要异步执行多个任务,你必须: 为每个对象定义一个函数(

  • 我试图按照这篇文章将cucumber规格与IntelliJ中的步骤定义相匹配。 当我按Alt Enter时,我看到检查未定义的步骤选项。但是,我应该看到意图操作创建步骤定义。 我想我已经安装了Cucumber IntelliJ插件,所以这应该不是问题。非常感谢任何帮助。