如何在循环中链接异步ajax函数 [英] How to chain an async ajax function in a loop

查看:102
本文介绍了如何在循环中链接异步ajax函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想链接一个异步ajax函数,该函数在一个循环中被多次调用.为什么?因为该功能是上传文件,但我希望它顺序上传文件,而不是一次上传所有文件.我不想使用async false,因为我希望在DOM上更新进度.

I would like to chain an asynchronous ajax function that is called several times within a loop. Why? Because that function is to upload files but I want it to serially upload files rather than uploading all of them at once. I don't want to use async false because I want the progress updated on the DOM.

for (var i = 0; i < files.length; i++) {
         var fd = new FormData();

         fd.append('file', files[i]);
         fd.append('galleryid', galleryid);

        sendFileToServer(fd); //chain this function call
    }

function sendFileToServer(formData)
{
    var uploadURL ="includes/ajax/images/uploadImagePage.php"; //Upload URL
    var extraData ={}; //Extra Data.
    return jqXHR=$.ajax({
            xhr: function() {
            var xhrobj = $.ajaxSettings.xhr();
            if (xhrobj.upload) {
                    xhrobj.upload.addEventListener('progress', function(event) {
                        var percent = 0;
                        var position = event.loaded || event.position;
                        var total = event.total;
                        if (event.lengthComputable) {
                            percent = Math.ceil(position / total * 100);
                        }
                        //Set progress
                       $('#uploadImageResponse').html(percent+'%');
                    }, false);
                }
            return xhrobj;
        },
    url: uploadURL,
    type: "POST",
    async:true,
    contentType:false,
    processData: false,
        cache: false,
        data: formData,
        success: function(data){
            status.setProgress('Upload completed. 100%.');

        }
    }); 


}

我不明白jquery延迟对象的工作方式.

I don't understand how jquery deferred objects work.

推荐答案

有很多不同的方法可以序列化多个请求,例如这样.这是一种使用手动迭代而不是for循环的方法,因此只有在前一个迭代完成后才前进到下一个迭代.

There are a number of different approaches for serializing multiple requests like this. Here's one way that uses a manual iteration instead of the for loop so you only advance to the next iteration when the previous one has completed.

手动迭代

function sendAllFiles(files) {
    var index = 0;

    function next() {
        var fd;
        if (index < files.length) {
            fd = new FormData();
            fd.append('file', files[index]);
            fd.append('galleryid', galleryid);
            ++index;
            // send this file and when done, do the next iteration
            sendFileToServer(fd).then(next);
        } else {
            // all files are done now
        }
    }
    // start the first iteration
    next();
}


使用.reduce()


Chained promises using .reduce()

而且,这是使用.reduce()和链接的诺言的另一种设计模式:

And, here's a different design pattern using .reduce() and chained promises:

files.reduce(function(p, item) {
    return p.then(function() {
        var fd = new FormData();
        fd.append('file', item);
        fd.append('galleryid', galleryid);
        return sendFileToServer(fd);
    });
}, $.Deferred().resolve()).then(function() {
    // all files are done now
});

这篇关于如何在循环中链接异步ajax函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆