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)
执行顺序如下:
该进程正在执行actionDefaultBasemap() 中的then(),但未到达loadBasemap() 中的then()。
不确定该过程在哪里中断。我需要将地图对象返回到
view = loadView(MAP_CANVAS_ID, map);
Run Code Online (Sandbox Code Playgroud)
任何建议都会有帮助。
new Promise(function () {
updateToDefaultLayerSetting();
}).then(...
Run Code Online (Sandbox Code Playgroud)
构造new Promise函数存在的原因之一是:将 Promise 包装在不使用 Promise 的事物(例如回调)周围。如果您要为此使用它,则需要调用resolve或reject回调,如下所示:
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语法,请等待承诺,然后返回您希望函数承诺解析的内容。