使用Azure平台访问数组位置在JavaScript中返回undefined

时间:2015-05-26 00:01:10

标签: javascript arrays azure serverside-javascript

我有以下JavaScript对象:

var payload = {
    "data": {
        "title": item.title,
        "time": item.time,
        "location": item.location,
        "latitude": item.latitude,
        "longitude": item.longitude,
        "invites": item.invites,
        "encodedImage": item.encondedImage        
    }
};

item.invites是一个用逗号分隔的大字符串。我使用函数将字符串拆分为基于逗号的数组:

var userIdArray = splitArray(item.invites);
userIdArray.pop(); //last element is empty

//further down...
function splitArray(str) {
    var array = new Array(); //explicitly declared out of despair
    array = str.split(",");    
    return array;
}

然后我像这样迭代它:

for (var i = 0; i < userIdArray.length; i++) {
     request.execute({
         success: function() {
            console.log("User: " + userIdArray[i]); //prints undefined...

但即使console.log(userIdArray);正常打印数组,如果数组长度只有1,我会得到未定义,但如果它是2,则会打印 2nd 元素。为什么会这样?

1 个答案:

答案 0 :(得分:1)

我不熟悉Azure,但是按照代码的一般模式,似乎success是一个将来会执行的函数,并且不依赖于循环范围:因此它将会在处理程序执行时看到一个错误的计数器变量[i]值。

(另外,它可能不会造成问题,但在循环标题中声明和初始化的计数器变量是代码气味,并且可能存在问题。)

在不查看完整代码的情况下,我无法判断[i]是否为包装函数的全局或局部,但我认为它是全局的,因为您没有得到ReferenceError。

循环执行时不等待所有未来的成功调用(它们是异步堆叠的并且与循环体不同步),因此最后的[i++]在array.length处进行评估,它始终是因为我们正在索引数组,所以未定义。

request.execute是同步的,将从循环体内按预期调度,但成功处理程序肯定不会。

至于在代码中正确表达意图,我认为IIFE可能会解决这个问题:(我不知道request.execute做了什么,如果同时在同一个对象上调用execute就可以了,因此我说出来可能):

for (var i = 0; i < userIdArray.length; i++) {
     request.execute({
        success: (function (counter) {
            return function () {
                console.log("User: " + userIdArray[counter]);
            }
        }(i))
    });
 }

我在这里抛出一个合理的猜测。除此之外,我认为代码需要重新思考和重构。循环中的回调通常表明存在一个主要的逻辑缺陷。