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

如何解决jQuery Promise的.then()在AJAX执行完成前触发的问题

问题根源

你的代码存在两层异步操作,仅对第一层$.ajax请求做了Promise封装,没有处理第二层的图层查询异步逻辑:
retrieveTrees函数内部的userLayer.query().where().run()是异步回调方法,retrieveTrees不会等待回调执行完成,就会直接返回userLayer对象。此时你在外层Promise的success回调里直接resolve(retrieveTrees(response)),会导致.then()触发时,run回调里的userLayer.addTo(map)逻辑还没有执行,自然打印的map.hasLayer(userLayer)为false。

修复方案

1. 改造retrieveTrees函数,使其返回Promise

将图层查询和添加的逻辑也封装进Promise,等图层成功添加到地图后再resolve:

function retrieveTrees(response) {
  return new Promise((resolve, reject) => {
    let conditionalVal = " or ";
    let treeID = "";

    for(let i=0; i<response.length; i++) {
      treeID = response[i]['MYTreeID']
      if(i==0) {
          all_trees = `${IMP_FIELDS.TREEMAIL_SEARCH} like '%${treeID}%'`;
      } else {
          all_trees += conditionalVal + `${IMP_FIELDS.TREEMAIL_SEARCH} like '%${treeID}%'`;
      }
    }

    console.log("所有树ID",all_trees);

    queryString = all_trees + ` and Actual_Tree_Type like '%${featureType}%'`;

    let layerOptions = $.extend(
      {
        where: queryString
      },
      userPlottedLayerView18Options
    );

    layerOptions.url = mapLayers.userPlantedLayer;
    userLayer = L.esri.featureLayer(layerOptions);

    userLayer
      .query()
      .where(queryString)
      .run((err, featureCollection, response) => {
        if (err) {
          return reject(err);
        }
        if (featureCollection.features.length > 0) {
          removeClass($loadingDiv, 'show');
          //将userLayer添加到地图上
          userLayer.addTo(map);
          console.log(map.hasLayer(userLayer), "AJAX内部检查")
        }
        // 操作完成后resolve,把userLayer传出去
        resolve(userLayer);
    });
  })
}

2. 调整外层Promise的resolve逻辑

因为retrieveTrees现在返回Promise,直接把它作为resolve的参数即可,Promise会自动等待内部异步完成后再触发外层的.then():

return new Promise(function(resolve, reject){
  $.ajax({
    url: "../apis/treemailSearch",
    method: 'GET',
    dataType: 'json',
    data : configData,
    contentType: 'application/json',
    success: response => {
      // 直接resolve retriveTrees返回的Promise
      resolve(retrieveTrees(response));
    },
    error : function(err){
      reject(err, "此处打印错误");
    }
  });
})

3. 修正调用处的userLayer赋值逻辑

你原来的代码把addUserLayerTreemail返回的Promise赋值给了userLayer,这是错误的,需要在.then()回调里接收返回的图层对象:

// 不要直接把Promise赋值给userLayer
this.addUserLayerTreemail(
  $loadingContent,
  $loadingDiv,
  treeLayers,
  map,
  heritage_cluster_layer_view_18,
  flowering_cluster_layer_view_18,
  IMP_FIELDS,
  suggestion,
  userPlottedLayerView18Options,
  userLayer,
  $speciesError
).then( function(userLayer){
  // 在这里接收返回的图层对象
  console.log(map.hasLayer(userLayer), "检查图层是否存在")
  setSearchState(true);
  $mapSearch.blur();
}).catch(function(err){
  console.log("捕获到错误", err)
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:27:03