在循环

时间:2017-05-23 14:37:42

标签: javascript jquery ajax

这是我要做的事情的本质......

创建一个让用户提交休假请求的简单页面。如果请求的类型为“请假”,则需要注明。因此,如果请求类型为“Leave of Absence”,请对服务器执行Ajax调用以获取此请求的注释计数。如果它为零,则停止该过程。如果是> 0,然后保存请求。

我试图用承诺来做这件事,但我做错了......

for (var i = 0; i < VacationRequests.length; i++)
{
    if (VacationRequests[i].VacationRequestType == leaveOfAbsenceType)
    {
        GetNoteCountPromise.then(function(result) {
            SaveVacationRequest(VacationRequests[i]);
        }, function(err) {
           $('#LeaveOfAbsenceModal').modal('show');
           return;
        });
    }
}

这是承诺......

    var GetNoteCountPromise = new Promise(function(resolve, reject) {
        $.ajax({
            url: '@Url.Action("GetNoteCount", "VacationRequests")',
            type: 'GET',
            dataType: 'json',
            data: { VacationRequestId: vacationRequestId },
            success: function(data) {
                if (data > 0) {
                    resolve(true);
                }
                else {
                    reject(false);
                }
            }
        });
    });

第一个问题:

我不知何故需要将vacationRequestId传递给承诺。不知道怎么做。

第二个问题:

我这样做了吗?

修改

这是我先做的事情:

for (var i = 0; i < VacationRequests.length; i++)
{
    if (VacationRequests[i].VacationRequestType == leaveOfAbsenceType)
    {
        $.ajax({
            url: '@Url.Action("GetNoteCount", "VacationRequests")',
            type: 'GET',
            dataType: 'json',
            data: { VacationRequestId: vacationRequestId },
            success: function(data) {
                if (data > 0) {
                    SaveVacationRequest(VacationRequests[i]); /// THIS is where it broke down
                }
                else {
                    $('#LeaveOfAbsenceModal').modal('show');
                    return;
                }
            }
        });
    }
}

问题在于,当我们点击Success方法时,循环已经完成,VacationRequests[i]未定义。

2 个答案:

答案 0 :(得分:1)

  

问题在于,当我们点击Success方法时,循环已经完成,而且VacationRequests [i]未定义。

要解决此问题(请参阅closure),您可以使用IIFE

另一种解决方案可以基于javaScript let

&#13;
&#13;
var leaveOfAbsenceType = 1;
var VacationRequests = [{VacationRequestType: 1, VacationRequestId: 1}, {VacationRequestType: 1, VacationRequestId: 2}]
for (var i = 0; i < VacationRequests.length; i++)
{
    if (VacationRequests[i].VacationRequestType == leaveOfAbsenceType)
    {
        (function(i) {
            $.ajax({
                url: 'https://api.github.com/users/octocat/orgs',
                type: 'GET',
                dataType: 'json',
                data: { VacationRequestId: VacationRequests[i].vacationRequestId },
                success: function(data) {
                    console.log('success -->' + i);
                },
                errror: function() {
                    console.log('errror -->' + i);
                }
            });
        })(i);
    }
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您的问题是,当您从服务器收到回复时,我是VacationRequests.length(因此比最高索引大1)。当您刚刚进入异步编程时,这是一个经常遇到的问题。为了说明问题:

&#13;
&#13;
for(var i = 0; i < 5; i++){
  setTimeout(function(){
    console.log(i);
    }, 0);
}
&#13;
&#13;
&#13;

您可以通过利用IIFE并确定变量范围来解决此问题。

for (var i = 0; i < VacationRequests.length; i++)
{
    function scoping(i){
        if (VacationRequests[i].VacationRequestType == leaveOfAbsenceType)
        {
             var VacationRequestId = i;//or whatever the id is at this location
             GetNoteCountPromise(VacationRequestId).then(function(result) {
                SaveVacationRequest(VacationRequests[i]);
            }, function(err) {
               $('#LeaveOfAbsenceModal').modal('show');
               return;
            });
        }
    }(i)
}

var GetNoteCountPromise = function(vacationRequestId){
return new Promise(function(resolve, reject) {
    $.ajax({
        url: '@Url.Action("GetNoteCount", "VacationRequests")',
        type: 'GET',
        dataType: 'json',
        data: { VacationRequestId: vacationRequestId },
        success: function(data) {
            if (data > 0) {
                resolve(true);
            }
            else {
                reject(false);
            }
        }
    });
});
};

此外,我们可以将vacationRequestId放入一个闭包中,以使其可以访问承诺。