JavaScript Promise with Ajax 在循环内调用



这就是我想要做的本质......

创建允许用户提交休假请求的简单页面。 如果请求类型为"请假",则需要备注。 因此,如果请求类型为"请假",请对服务器进行 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]尚未定义。

这样做的问题是,当我们点击 Success 方法时,循环已经完成,并且 VacationRequests[i] 尚未定义。

为了解决这个问题(参考闭包(,您可以使用IIFE。

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

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);
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

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

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

您可以通过利用 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 放入闭包中,以使其可访问承诺。

最新更新