Javascript 如何知道XMLHttpRequest是否已完成?

Javascript 如何知道XMLHttpRequest是否已完成?,javascript,jquery,upload,xmlhttprequest,photo,Javascript,Jquery,Upload,Xmlhttprequest,Photo,我正在上载多个带有表单字段的文件 <input type="file" accept="image/jpeg, image/png" multiple 我的问题是,重定向是在所有上传完成之前完成的。如何使脚本等待所有xmlhttprequests完成 编辑 我把上传功能改成这样,用jQuery上传。该函数在for循环中被多次调用,因此我如何等待所有循环/jquery调用完成,然后重定向 function upload (photo, callback) { var f

我正在上载多个带有表单字段的文件

<input type="file" accept="image/jpeg, image/png" multiple 
我的问题是,重定向是在所有上传完成之前完成的。如何使脚本等待所有xmlhttprequests完成


编辑 我把上传功能改成这样,用jQuery上传。该函数在for循环中被多次调用,因此我如何等待所有循环/jquery调用完成,然后重定向

function upload (photo, callback) {
        var fd = new FormData();
        fd.append('photo',photo);

        return $.ajax({
            url: 'upload.php',
            type: 'post',
            data: fd,
            contentType: false,
            processData: false,
            success: function(response){

            },
        });
    };

可以在回调中递增全局计数器变量。当它达到数组长度时,所有请求都已完成

var completed = 0;
for (var i = 0; i < files.length; i++) {
    upload(resizedFile, function (response) {
        if (++completed == files.length) {
            window.location = redirect_url;
        }
    });
}
var completed=0;
对于(var i=0;i
您可以在回调中增加一个全局计数器变量。当它达到数组长度时,所有请求都已完成

var completed = 0;
for (var i = 0; i < files.length; i++) {
    upload(resizedFile, function (response) {
        if (++completed == files.length) {
            window.location = redirect_url;
        }
    });
}
var completed=0;
对于(var i=0;i
首先,我要说明上传功能。使用JQuery会短得多,因为
$。ajax
返回一个thenable对象,但是使用老式的vanilla JS,它会如下所示:

var upload = function (photo) {
    return new Promise(function(resolve, reject) {
        var request = new XMLHttpRequest();

        request.onload = function() {
            if (request.status >= 200 && request.status < 300) {
                resolve(request.response);
            } else {
                reject(request.statusText);
            }
        };      
        request.onerror = function() { reject(request.statusText) }
        request.open('POST', 'upload.php');
        request.responseType = 'json';

        var formData = new FormData();
        formData.append('photo', photo);
        request.send(formData);
    })
}
(或者简单地进行迭代并将它们推送到数组中)

然后,您可以使用此代码处理所有上载的完成:

Promise.all(uploads)
   .then(function(results) { /* do the redirect */ })
   .catch(function(error) { console.log(error); });
另见:

注意:为什么其他答案中建议的计数错误?因为它不处理任何请求失败时的条件。您将无法检测到该情况,并且您将永远无法达到要满足的条件。承诺(和异步/等待)是处理异步操作(如ajax请求)的正确方法

[更新]

以下是使用最新JS语言功能的JQuery方法:

var upload = (photo) => {
   photo = resizeFile(photo);

   let formData = new FormData();
   formData.append('photo', photo);
   return $.ajax({
     type: 'POST',
     url: 'upload.php',
     data: formData
   }) // check other the options of ajax method, you might need them
}

let uploads = files.map(upload);

$.when.apply($,uploads)
  .done(_ => { /* do the redirect */ })
  .fail(e => { /* handle error */ })
后一部分可以使用
async/await
语法编写:

async somefunction(){ 

  // rest of the code

  try {
     await $.when.apply($,uploads)
     /* do the redirect */
  } catch(ex) {
     /* handle error */
  }
}
请注意,
$.ajax
返回一个JQuery对象,它与Promise兼容。

首先,我要说明upload函数。使用JQuery会短得多,因为
$。ajax
返回一个thenable对象,但是使用老式的vanilla JS,它会如下所示:

var upload = function (photo) {
    return new Promise(function(resolve, reject) {
        var request = new XMLHttpRequest();

        request.onload = function() {
            if (request.status >= 200 && request.status < 300) {
                resolve(request.response);
            } else {
                reject(request.statusText);
            }
        };      
        request.onerror = function() { reject(request.statusText) }
        request.open('POST', 'upload.php');
        request.responseType = 'json';

        var formData = new FormData();
        formData.append('photo', photo);
        request.send(formData);
    })
}
(或者简单地进行迭代并将它们推送到数组中)

然后,您可以使用此代码处理所有上载的完成:

Promise.all(uploads)
   .then(function(results) { /* do the redirect */ })
   .catch(function(error) { console.log(error); });
另见:

注意:为什么其他答案中建议的计数错误?因为它不处理任何请求失败时的条件。您将无法检测到该情况,并且您将永远无法达到要满足的条件。承诺(和异步/等待)是处理异步操作(如ajax请求)的正确方法

[更新]

以下是使用最新JS语言功能的JQuery方法:

var upload = (photo) => {
   photo = resizeFile(photo);

   let formData = new FormData();
   formData.append('photo', photo);
   return $.ajax({
     type: 'POST',
     url: 'upload.php',
     data: formData
   }) // check other the options of ajax method, you might need them
}

let uploads = files.map(upload);

$.when.apply($,uploads)
  .done(_ => { /* do the redirect */ })
  .fail(e => { /* handle error */ })
后一部分可以使用
async/await
语法编写:

async somefunction(){ 

  // rest of the code

  try {
     await $.when.apply($,uploads)
     /* do the redirect */
  } catch(ex) {
     /* handle error */
  }
}

请注意,
$.ajax
返回一个JQuery对象,它与Promise兼容。

为每个请求创建一个承诺,然后使用
Promise.all()
等待所有请求。如何做?为每个请求创建一个承诺,然后使用
Promise.all()
等待所有这些。如何做到这一点?感谢您的回答和解释。。使用jQueryAjax会是什么样子?它会比承诺更短/更简单吗?请看我上面的编辑。。我已将上载功能更改为jquery。。但是,如果所有上传都已完成,我如何在for循环中检查。。然后重定向@阿尔迪,请仔细阅读我的全部更新。我发布的方法返回一个
延迟的
(类似于
承诺
)。我已将所有上载映射到一个数组中。这意味着我有一组不同的s。现在,最后一部分是
$。当
将它们组合在一个单独的延迟中时,将完成或失败。另一方面,您可以在一个请求中轻松上载多个文件。感谢您的回答和解释。。使用jQueryAjax会是什么样子?它会比承诺更短/更简单吗?请看我上面的编辑。。我已将上载功能更改为jquery。。但是,如果所有上传都已完成,我如何在for循环中检查。。然后重定向@阿尔迪,请仔细阅读我的全部更新。我发布的方法返回一个
延迟的
(类似于
承诺
)。我已将所有上载映射到一个数组中。这意味着我有一组不同的s。现在,最后一部分是
$。当
将它们组合在一个单独的延迟中时,将完成或失败。另一方面,您可以在一个请求中轻松上载多个文件。