Javascript Promise 不进入 then()

jat*_*ats 0 javascript promise

我对 JavaScript Promise 有一个问题,其中一个 Promise 没有进入 then()

下面是我试图完成的代码。

背景:我之前没有使用过Promise,但是看过几篇文章。

    function doStart(){        
    var loadedMap = loadBasemap([layer0]);
    loadedMap.then(function (v) {
            view = loadView(MAP_CANVAS_ID, map);
            ...
        });
    ...
}
    
 function loadBasemap(layers) {
    if (LayerSettings && LayerSettings.hasOwnProperty('basemap') && LayerSettings.basemap.hasOwnProperty('baseMapLayers')) {
        new Promise(function () {
            updateToDefaultLayerSetting();
        }).then(function () {
            map = new Map({
                basemap: Basemap.fromJSON(LayerSettings.basemap),
                layers: layers
            });
        });
        return new Promise((resolve, reject) => resolve(map));
    }
    else {...}
}

async function updateToDefaultLayerSetting() {
    console.log("Calling default");
    const result = await actionDefaultBasemap();
    console.log(result);
}

var defaultBasemap;
function actionDefaultBasemap() {
    let portalA = new Portal(portalConfig);
    
    new Promise(function () {
        portalA.load().then(function () {
            defaultBasemap = portalA.useVectorBasemaps ? portalA.defaultVectorBasemap : portalA.defaultBasemap;
        }).then(function () {
            if (LayerSettings.basemap.baseMapLayers[0].hasOwnProperty('url') && typeof defaultBasemap.resourceInfo !== "undefined") {
                LayerSettings.basemap.baseMapLayers[0].id = defaultBasemap.resourceInfo.data.baseMapLayers[0].id;
                LayerSettings.basemap.baseMapLayers[0].title = defaultBasemap.resourceInfo.data.baseMapLayers[0].title;
                LayerSettings.basemap.baseMapLayers[0].url = defaultBasemap.resourceInfo.data.baseMapLayers[0].url;
            }
        });
    })

    return new Promise((resolve, reject) => resolve(defaultBasemap));
}
Run Code Online (Sandbox Code Playgroud)

执行顺序如下:

  1. doStart()
  2. 加载底图(图层)
  3. updateToDefaultLayerSetting()
  4. 动作默认底图()

该进程正在执行actionDefaultBasemap() 中的then(),但未到达loadBasemap() 中的then()。

不确定该过程在哪里中断。我需要将地图对象返回到

view = loadView(MAP_CANVAS_ID, map);
Run Code Online (Sandbox Code Playgroud)

任何建议都会有帮助。

Nic*_*wer 5

new Promise(function () {
   updateToDefaultLayerSetting();
}).then(...
Run Code Online (Sandbox Code Playgroud)

构造new Promise函数存在的原因之一是:将 Promise 包装在不使用 Promise 的事物(例如回调)周围。如果您要为此使用它,则需要调用resolvereject回调,如下所示:

new Promise(function (resolve, reject) {
  setTimeout(() => {
    if (Math.random() > 0.5) {
      resolve('success!');
    } else {
      reject('error');
    }
  }, 1000);
});
Run Code Online (Sandbox Code Playgroud)

您的代码永远不会调用resolveor reject,因此 中的代码.then永远不会发生

但实际上你根本不需要打电话new Promise,因为你已经有了承诺!updateToDefaultLayerSetting返回一个 Promise(你可以知道,因为它是一个异步函数),这意味着 loadBaseMap 可以写成如下:

function loadBasemap(layers) {
  if (LayerSettings && LayerSettings.hasOwnProperty("basemap") && LayerSettings.basemap.hasOwnProperty("baseMapLayers")) {
    return updateToDefaultLayerSetting().then(function () {
      return new Map({
        basemap: Basemap.fromJSON(LayerSettings.basemap),
        layers: layers,
      });
    });
  } else {...}
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,调用.thenPromise 会创建一个新的 Promise。新的 Promise 将通过回调函数最终返回的任何内容来解决。因此 loadBasemap 返回一个将解析为Map.

如果您更喜欢对 async/await 执行相同的操作(我知道我这样做),那么它看起来像:

async function loadBasemap(layers) {
  if (LayerSettings && LayerSettings.hasOwnProperty("basemap") && LayerSettings.basemap.hasOwnProperty("baseMapLayers")) {
    await updateToDefaultLayerSetting();
    return new Map({
      basemap: Basemap.fromJSON(LayerSettings.basemap),
      layers: layers,
    });
  } else {...}
}
Run Code Online (Sandbox Code Playgroud)

actionDefaultBasemap还需要一些重写,我没有包括在内。它也有同样的问题:在不需要的地方创建新的承诺,然后永远不会解决新的承诺。PortalA.load() 已经返回了一个承诺,因此可以以此为基础进行构建。

如果您更喜欢.then语法,请调用.thenPromise 并在回调中返回您希望新 Promise 解析的内容。如果您更喜欢async/await语法,请等待承诺,然后返回您希望函数承诺解析的内容。