簡體   English   中英

僅在 javascript 循環完成后才執行 ajax 調用

[英]Execute ajax call only after javascript loop has finished

下面是我正在使用的代碼,它基本上傳遞了要上傳的多個文件。 在循環中,每個文件都會在客戶端調整大小,然后上傳。

我想在循環完成上傳照片后執行 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;
}

您可以將 $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();
        }
    }
} 

您可以使用任何承諾庫來執行此操作。 這是使用 jQuery 承諾的示例

     (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/

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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM