You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中如何等待AJAX命令执行完成?

嘿,我太懂你现在的抓狂了!刚摸JavaScript的时候,异步AJAX这个坑真的特别容易踩——你调用那些year1fun、cc1fun这类AJAX函数时,JS根本不会乖乖停下来等服务器返回结果,直接就跳去执行后面的document.getElementById...代码了,完全打乱了你想要的执行顺序对吧?

为啥会这样?

这是因为AJAX默认是异步的,简单说就是JS把AJAX请求“甩”给浏览器去处理,自己接着往下跑代码,完全不等服务器响应回来。所以你的DOM赋值操作会在AJAX请求还没完成的时候就执行了,自然达不到预期效果。

怎么解决?

核心思路就是:让后续的DOM操作必须等AJAX请求完成后再执行,下面给你两种适合新手的方案,从基础到进阶都有:


方案1:用回调函数(基础款)

如果你的year1fun这类AJAX函数支持传入回调,就可以把要等AJAX完成后执行的代码塞进回调里。

首先修改你的AJAX函数,让它接受一个回调参数:

// 以year1fun为例,改造后支持回调
function year1fun(yearVal, a, callback) {
  const xhr = new XMLHttpRequest();
  xhr.open('POST', '你的接口地址'); // 替换成你的实际接口
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  
  xhr.onload = function() {
    if (xhr.status === 200) {
      // 服务器返回成功后,执行回调
      callback(null, xhr.responseText);
    } else {
      callback(new Error('year请求失败'));
    }
  };
  
  xhr.onerror = function() {
    callback(new Error('网络出错啦'));
  };
  
  xhr.send(`year=${yearVal}&a=${a}`);
}

// cc1fun、tp1fun也按照同样的方式改造,加上callback参数

然后在putthedataback里,把DOM操作放到回调的嵌套里(确保顺序执行):

function putthedataback() {
  for (var i = 0; i < year.length; i++) {
    // 用立即执行函数解决var的作用域问题,避免循环变量混乱
    (function(i) {
      var a = i + 1;
      // 先等year1fun完成,再执行cc1fun,接着tp1fun,最后更新DOM
      year1fun(year[i], a, function(err, res) {
        if (err) {
          console.error('year请求出错:', err);
          return;
        }
        cc1fun(cc[i], a, function(err, res) {
          if (err) {
            console.error('cc请求出错:', err);
            return;
          }
          tp1fun(tp[i], a, function(err, res) {
            if (err) {
              console.error('tp请求出错:', err);
              return;
            }
            // 所有AJAX都完成了!现在更新DOM
            document.getElementById("year" + a).value = "" + year[i];
            document.getElementById("cc" + a).value = "" + cc[i];
            // 这里补全你其他的DOM赋值代码
          });
        });
      });
    })(i);
  }
}

方案2:用Promise + async/await(进阶款,更清晰)

回调嵌套多了容易变成“回调地狱”,现在更推荐用Promise配合async/await,代码可读性高很多。

首先把AJAX函数改成返回Promise:

// 改造year1fun为返回Promise
function year1fun(yearVal, a) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', '你的接口地址');
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    
    xhr.onload = function() {
      if (xhr.status === 200) {
        resolve(xhr.responseText); // 请求成功,把结果传出去
      } else {
        reject(new Error('year请求失败')); // 请求失败,抛出错误
      }
    };
    
    xhr.onerror = function() {
      reject(new Error('网络出错啦'));
    };
    
    xhr.send(`year=${yearVal}&a=${a}`);
  });
}

// cc1fun、tp1fun也改成同样的返回Promise形式

然后把putthedataback改成async函数,用await等待每个AJAX完成:

async function putthedataback() {
  // 用let代替var,避免循环作用域问题
  for (let i = 0; i < year.length; i++) {
    let a = i + 1;
    try {
      // 顺序等待三个AJAX请求完成
      await year1fun(year[i], a);
      await cc1fun(cc[i], a);
      await tp1fun(tp[i], a);
      
      // 所有请求都完成了,再更新DOM
      document.getElementById("year" + a).value = "" + year[i];
      document.getElementById("cc" + a).value = "" + cc[i];
      // 补全其他DOM赋值代码
    } catch (err) {
      // 捕获错误,避免一个请求失败导致整个循环中断
      console.error(`第${a}组请求出错:`, err);
    }
  }
}

如果这三个AJAX请求不需要顺序执行(可以同时发起),还能用Promise.all提高效率:

async function putthedataback() {
  for (let i = 0; i < year.length; i++) {
    let a = i + 1;
    try {
      // 同时发起三个请求,等所有请求都完成再继续
      await Promise.all([
        year1fun(year[i], a),
        cc1fun(cc[i], a),
        tp1fun(tp[i], a)
      ]);
      
      // 更新DOM
      document.getElementById("year" + a).value = "" + year[i];
      document.getElementById("cc" + a).value = "" + cc[i];
      // 补全其他DOM赋值代码
    } catch (err) {
      console.error(`第${a}组请求出错:`, err);
    }
  }
}

小提示

如果你用的是jQuery的$.ajax,它本身就支持Promise,直接用async/await就行,不用自己封装Promise哦~

内容的提问来源于stack exchange,提问作者Avon97

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:49:13