You need to enable JavaScript to run this app. JavaScript Async/Await 不生效:如何实现代码按1-2-3-4顺序执行
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript Async/Await 不生效:如何实现代码按1-2-3-4顺序执行

核心代码错误与修正方案

目前代码存在的3个硬错误

  • 死代码导致日志4不执行:JS函数执行到return语句后会立刻终止运行,后续写的所有代码都属于永远不会触发的无效代码,你把console.log("ending function")写在了return后面,自然永远看不到输出。
  • 异步对象取错值:setBoltEnum是普通函数,内部既没有return值,也没有创建带array属性的对象;你用new setBoltEnum()拿到的是一个完全空的实例,它上面根本不存在array属性,所以await result.array拿到的永远是undefined,完全绕过了AJAX的异步返回流程。
  • 执行顺序错配:因为没有正确await AJAX返回的Promise,你在调用setBoltEnum后立刻同步执行标3的日志,不等AJAX响应回来就先把undefined打了出来,等AJAX异步回调跑完才会执行标2的日志,最终顺序完全混乱。

修正后的可运行代码

1. 重写AJAX处理函数setBoltEnum

去掉不必要的全局变量赋值,直接返回jQuery的AJAX Promise对象:

function setBoltEnum(Thread_Code){
    console.log(Date.now() + " - 1 - calling AJAX");
    // 直接return $.ajax返回的Promise,不要赋值给全局变量
    return $.ajax({
        url: 'EnumHelper.php',
        type: 'POST',
        dataType: "html",
        data: {
            value: Thread_Code,
            col_out: 'Descr',
            col_search: 'Thread_Code',
            tablename: 'Bolt_List'
        },
        success: function (response) {
            const parsedResult = JSON.parse(response);
            console.log(Date.now() + " - 2 - got AJAX response: " + parsedResult.resp);
            return parsedResult;
        },
        error: function(XMLHttpRequest, textStatus, exception) { 
            alert("Ajax failure\n" + errortext); 
        },
        async: true
    });
}

2. 调整枚举提供函数的执行逻辑

把return语句移到所有日志输出的最后,正确await AJAX返回的结果:

DatabaseGrid.prototype.initializeGrid = function(grid) {
  var self = this;
    grid.setEnumProvider('id_Bolt', new EnumProvider({ 
        getOptionValuesForEdit: async function (grid, column, rowIndex) {
            var Thread_Code = grid.getValueAt(rowIndex, grid.getColumnIndex("Thread_Code"));
            // 直接await setBoltEnum返回的Promise,不要用new,不要取不存在的array属性
            const enumResult = await setBoltEnum(Thread_Code);
            console.log(Date.now() + " - 3 - " + enumResult.Descr);
            console.log(Date.now() + " - 4 - " + "ending function");
            // 所有逻辑跑完再return结果,这才不会产生死代码
            return enumResult.Descr;
        }
    }));
};

执行顺序说明

修正后流程完全符合预期:

  1. 触发单元格编辑调用async函数,同步进入setBoltEnum打印标1日志
  2. 触发异步AJAX请求,async函数因await关键字暂时挂起,不阻塞后续页面操作
  3. AJAX请求完成,进入成功回调打印标2日志,把解析后的响应作为Promise的返回值
  4. 回到挂起的async函数,拿到AJAX返回结果,依次打印标3、标4日志
  5. 最终把枚举选项值返回给editablegrid完成单元格渲染

注意:editablegrid文档提到的“AJAX需使用同步模式”是基于老旧的同步阻塞JS逻辑写的,如果你用现在的async函数作为回调,它返回的是Promise对象,需要确认editablegrid源码在调用getOptionValuesForEdit时有没有做await处理——如果没有,哪怕你内部逻辑写的没问题,网格拿到的也会是Promise对象而不是实际的枚举值。不需要刻意把AJAX改成async:false的同步模式,这种写法现在浏览器会抛出控制台警告,还会直接卡死页面交互。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 16:24:09