仅在javascript循环结束后执行ajax调用

时间:2015-06-26 22:15:57

标签: javascript php jquery ajax

以下是我使用的代码,它基本上传递了多个要上传的文件。在循环中,每个文件都在客户端调整大小,然后上传。

我希望在循环完成上传照片后执行ajax调用。 ajax调用基本上会重新加载特定的div并刷新照片。

如何阻止ajax调用执行,直到循环结束。

if (window.File && window.FileReader && window.FileList && window.Blob)
    {       
        var files = document.getElementById('filesToUpload').files;    
        for(var i = 0; i < files.length; i++) 
        {
            resizeAndUpload(files[i]);


        }

        // when loop finished, execute ajax call
            $.ajax
            ({
                type: "POST",
                url: "photos.php",
                data: dataString,
                success: function(html)
                {
                    $("#photo-body").html(html);
                }       
            });
        }       
    }

function resizeAndUpload(file)
{
    var reader = new FileReader();
    reader.onloadend = function() 
    {
        var tempImg = new Image();
        tempImg.src = reader.result;
        tempImg.onload = function()
        {
            var MAX_WIDTH = 382.25;
            var MAX_HEIGHT = 258.5;
            var tempW = tempImg.width;
            var tempH = tempImg.height;

            if (tempW > tempH) 
            {
                if (tempW > MAX_WIDTH)
                {
                    tempH *= MAX_WIDTH / tempW;
                    tempW = MAX_WIDTH;
                }
            } 
            else
            {
                if (tempH > MAX_HEIGHT)
                {
                    tempW *= MAX_HEIGHT / tempH;
                    tempH = MAX_HEIGHT;
                }
            }

            var canvas = document.createElement('canvas');
            canvas.width = tempW;
            canvas.height = tempH;
            var ctx = canvas.getContext("2d");
            ctx.drawImage(this, 0, 0, tempW, tempH);
            var dataURL = canvas.toDataURL("image/jpeg");

            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function(ev)
            {
                document.getElementById('filesInfo').innerHTML = 'Upload Complete';

            };
            xhr.open('POST', 'upload-resized-photos.php', true);
            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            var data = 'image=' + dataURL;
            xhr.send(data); 


        }
    }
    reader.readAsDataURL(file);
}

var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];    
function Validate(oForm)
{
    var arrInputs = oForm.getElementsByTagName("input");
    for (var i = 0; i < arrInputs.length; i++) 
    {
        var oInput = arrInputs[i];
        if (oInput.type == "file")
        {
            var sFileName = oInput.value;
            if (sFileName.length > 0)
            {
                var blnValid = false;
                for (var j = 0; j < _validFileExtensions.length; j++) 
                {
                    var sCurExtension = _validFileExtensions[j];
                    if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) 
                    {
                        blnValid = true;
                        break;
                    }
                }

                if (!blnValid) 
                {
                    alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
                    return false;
                }   
            }
        }
    }
    return true;
}

3 个答案:

答案 0 :(得分:1)

您可以在函数中包装$ ajax调用,并在最后一个循环结束时调用该函数。

(只是脚本的顶部)

if (window.File && window.FileReader && window.FileList && window.Blob) {       

    function loopFinished(){
        $.ajax
        ({
            type: "POST",
            url: "photos.php",
            data: dataString,
            success: function(html)
            {
                $("#photo-body").html(html);
            }       
        });
    }

    var files = document.getElementById('filesToUpload').files;    
    for(var i = 0; i < files.length; i++) 
    {
        resizeAndUpload(files[i]);
        if (files.length+1 == [i]){
            loopFinished();
        }
    }
} 

答案 1 :(得分:1)

您可以使用任何承诺库来执行此操作。以下是使用jQuery promise

的示例
     (function ($) {
        var files = [1, 2, 3, 4],
            allPromises = [];
        for (var i = 0; i < files.length; i++) {
            var promise = resizeAndUpload(files[i]);
            allPromises.push(promise);

        }

        $.when.apply($, allPromises).done(function () {
            makeAjaxCall();
        });

        function makeAjaxCall() {
            console.log('Put Ajax call here');
        }

        function resizeAndUpload(file) {
            var defer = $.Deferred();
//Set timeout simulates your long running process of processing file
            setTimeout(function () {
                console.log('processing file ' + file);
                defer.resolve();

            }, 2000);
            return defer.promise();
        }
    })(jQuery);

这是一个jSFiddle http://jsfiddle.net/x6oh471f/2/

答案 2 :(得分:0)

resizeAndUpload()函数中的一个或多个方法必须异步进行。这意味着他们会在后台执行他们的工作,而其他的javascript会运行,并且他们应该在完成后触发事件。一旦最后一个方法完成并触发事件,您将需要调用ajax方法。例如,fileReader方法是异步的。这意味着您可能需要执行以下操作:

FileReader.onloadend = function(){
   totalFilesLoaded = totalFilesLoaded + 1;
   if (totalFilesLoaded == files.length){
      //all files have been uploaded, run $ajax
   }
}

编辑:现在你已经上传了其余的代码,尝试这样的事情:

window.totalFilesLoaded = 0;
var files = document.getElementById('filesToUpload').files;
window.totalFilesToLoad = files;

if (window.File && window.FileReader && window.FileList && window.Blob)
    {       

        for(var i = 0; i < files.length; i++) 
        {
            resizeAndUpload(files[i]);
        }

    }

分开ajax功能:

window.runAjax = function(){
           $.ajax
            ({
                type: "POST",
                url: "photos.php",
                data: dataString,
                success: function(html)
                {
                    $("#photo-body").html(html);
                }       
            });
}
function resizeAndUpload(file)
{
    var reader = new FileReader();
    reader.onloadend = function() 
    {

    ...

            xhr.onreadystatechange = function(ev)
            {
                document.getElementById('filesInfo').innerHTML = 'Upload Complete';


                window.totalFilesLoaded++;
                if (window.totalFilesLoaded == window.totalFilesToLoad.length){
                    window.runAjax()
                }


            };

    ...

    }
    reader.readAsDataURL(file);
}