为何第二个alert输出undefined?Promise异步执行问题求助
为何第二个alert输出undefined?Promise异步执行的问题解析
你的问题核心是Promise的异步执行特性导致代码执行顺序和预期不符,具体拆解如下:
问题原因
- 所有Promise的
then回调函数都是异步任务,会被放到浏览器的事件队列中,等待当前所有同步代码执行完毕后才会依次触发。 - 代码最后一行的
alert(result)是同步代码,会在所有Promise回调之前运行——此时result仅被声明但未赋值,自然输出undefined。 - 第一个
alert(result)是在getRouteJSONBySynonymIds()的then回调里,这个回调要等前面所有Promise操作完成后才会执行,此时result已经被赋值为目标对象,所以能正常输出[object Object]。
修正方案
要让第二个alert也能拿到正确的result,必须把它放到异步回调的执行链中,保证它在result赋值之后运行。这里提供两种常见写法:
写法1:Promise链式调用(避免嵌套回调)
var result; function isAvailable() { return Promise.resolve(true); } function getOrdersManagement() { return new Promise(function(resolve) { var powerOrdersMPageUtils = { id: "Hello", value: "World" } isAvailable().then(function(isAvailable) { if (isAvailable) { resolve(powerOrdersMPageUtils); } }); }); } function hasMethodOnPowerOrdersHost() { return Promise.resolve(true); } function getRouteJSONBySynonymIds() { var object = { name: "getRouteJSONBySynonymIds" } return Promise.resolve(object); } function getRouteJSON() { var object = { name: "getRouteJSON" } return Promise.resolve(object); } // 重构后的链式调用 getOrdersManagement() .then(function() { return hasMethodOnPowerOrdersHost(); }) .then(function(methodExists) { if (methodExists) { return getRouteJSONBySynonymIds(); } else { return getRouteJSON(); } }) .then(function(object) { result = object; alert(result); // 第一个alert alert(result); // 第二个alert,此时已拿到赋值后的result });
写法2:使用async/await(更简洁的异步写法)
function isAvailable() { return Promise.resolve(true); } function getOrdersManagement() { return new Promise(function(resolve) { var powerOrdersMPageUtils = { id: "Hello", value: "World" } isAvailable().then(function(isAvailable) { if (isAvailable) { resolve(powerOrdersMPageUtils); } }); }); } function hasMethodOnPowerOrdersHost() { return Promise.resolve(true); } function getRouteJSONBySynonymIds() { var object = { name: "getRouteJSONBySynonymIds" } return Promise.resolve(object); } function getRouteJSON() { var object = { name: "getRouteJSON" } return Promise.resolve(object); } // 用async/await处理异步逻辑 async function fetchResult() { var result; // 等待所有异步操作完成 await getOrdersManagement(); const methodExists = await hasMethodOnPowerOrdersHost(); if (methodExists) { result = await getRouteJSONBySynonymIds(); } else { result = await getRouteJSON(); } alert(result); alert(result); } // 执行异步函数 fetchResult();
内容的提问来源于stack exchange,提问作者Hello
相关产品推荐
相关产品推荐

