【问题标题】:jQuery async ajax callsjQuery 异步 ajax 调用
【发布时间】:2020-03-13 07:57:53
【问题描述】:

我有下面的代码,它有一个列表,对于这个列表中的每个元素,做一个 ajax 调用。

util.testMethod = function(list) {

            var map = new Map();

            list.forEach(function(data) {
                $.ajax({
                    url: 'https://......',
                    type: 'GET',
                    data: // data needed here
                    success: function(data) {
                        // do something
                    },
                    error: function(jqxhr, settings, exception) {
                        // dos omething
                    }
                });
            });


            return map;
        };

由于我要进行一些异步 ajax 调用,我们假设其中有 1 个需要很长时间才能执行。这个 testMethod 是否有可能在 ajax 调用完成之前返回?

【问题讨论】:

    标签: javascript jquery ajax


    【解决方案1】:

    当然。 ajax 调用是异步的,因此代码将继续执行,无需等待成功/错误回调函数。

    你有两个选择:

    1. 将您的 ajax 调用设为同步调用(更多信息here
    2. (推荐) 将您的 testMethod 函数设为异步函数(更多信息 here

    但是 (1º选项)

    将 async 属性设置为 false 已弃用,正在处理中 被删除 (link)。包括 Firefox 和 Chrome 在内的许多浏览器都有 如果您使用它,已经开始在控制台中打印警告:

    并遵循 2º 选项的示例(更多关于 here 中的 javascript 承诺和 here 中的 Promise.All)

    async function makeAjaxCall()  {
        return new Promise((resolve) => {
            setTimeout(() => {
                // Just to make the makeAjaxCall 1 second slower;
                $.ajax({
                    url: 'http://www.mocky.io/v2/5e6ac7d32d0000db0c5fa686',
                    type: 'GET',
                    data: {},
                    success: function(data) {
                        resolve(data);
                    },
                    error: function(jqxhr, settings, exception) {
    
                         resolve({ error: 'OMG an ERROR!'});
                        // dos omething
                    }
                })
            }, 1000);
        });      
    };
    
    async function asynCall() {
      for(let i=0; i<10; i++) {
          // You can see in here that will wait 1 second before is going to the next ajax call
          const result = await makeAjaxCall();
          console.log(result);
      }
    }
    
    // You can run all your calls in paralel by using the Promise.All like this
    async function promiseAll() {
      const ajaxCalls = [];
      for(let i=0; i<10; i++) {
          ajaxCalls.push(makeAjaxCall());
      }
      
      //for this case, the calls will be made in parallel, which measn will take slight more than 1 second 
      Promise.all(ajaxCalls).then(function(values) {
        // will print the array of values which contains the values of each ajax call
        console.log(values);
      });
    }
    
    asynCall();
    promiseAll();
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 绝对不推荐选项#1,甚至可能在现代浏览器中都不可能
    • 有没有办法强制函数在返回之前等待所有 ajax 调用完成?似乎我可以使用 $.when 之类的东西,但这仅适用于固定数量的承诺。但就我而言,promise 的数量将与我的列表大小相同。
    • @Haobo_X 我对代码进行了更改。我希望这样的改变能解答你所有的疑惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 2012-05-04
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多