SAPUI5问题:JSONModel从API加载的数据无法在回调外访问
问题根源:异步请求的执行时机
你遇到的核心问题是JavaScript异步操作的执行顺序。oModel.loadData()是一个异步请求——它会立刻发起网络请求,但不会阻塞后续代码的执行。这就导致:
- 你写在外部的
console.log(b)和console.log(list),会在attachRequestCompleted回调触发之前就运行了 - 此时请求还没完成,
b还是初始的undefined,list是空数组;等请求完成后回调里的赋值确实会生效,但外部的打印已经早就执行过了,你看不到更新后的值
解决方案
方案1:把数据处理逻辑放在回调内部(最直接)
既然回调是请求完成后唯一能确保拿到数据的地方,就把所有需要使用数据的逻辑都移到这里面:
var oModel = new sap.ui.model.json.JSONModel(); var b; var list = []; oModel.attachRequestCompleted(function() { b = oModel.getData(); list.push(b); // 所有需要用数据的操作都放在这里 console.log(b); // 这里能拿到有效数据 console.log(list); renderUIWithData(b); // 比如渲染UI的函数 }); oModel.loadData("https://feiertage-api.de/api/?jahr=2014"); // 自定义的处理函数,把逻辑抽出来让代码更清晰 function renderUIWithData(data) { // 在这里写你需要用数据做的事情 }
方案2:用Promise封装,配合async/await(更优雅的同步写法)
如果你的运行环境支持ES6+,可以把请求逻辑封装成Promise,这样就能用async/await让代码看起来像同步执行:
// 封装一个返回Promise的加载函数 function loadModelData(url) { return new Promise((resolve, reject) => { const oModel = new sap.ui.model.json.JSONModel(); // 请求成功时返回数据 oModel.attachRequestCompleted(() => { resolve(oModel.getData()); }); // 别忘了处理请求失败的情况 oModel.attachRequestFailed((errorEvent) => { reject(errorEvent.getParameter("message")); }); oModel.loadData(url); }); } // 使用async/await来调用 async function fetchAndProcessData() { try { // 等待请求完成,拿到数据 const b = await loadModelData("https://feiertage-api.de/api/?jahr=2014"); const list = [b]; // 这里可以放心使用数据 console.log(b); console.log(list); // 其他数据处理逻辑... } catch (err) { console.error("加载数据失败:", err); } } // 执行函数 fetchAndProcessData();
为什么之前的尝试没用?
你之前把回调逻辑赋值给变量、或者在回调里给外部变量赋值,本质上还是没避开异步时机的问题——外部的代码依然会在请求完成前执行,所以打印的还是初始值。只有等回调触发后,外部变量才会被更新,但这时候你已经打印过了,自然看不到有效数据。
内容的提问来源于stack exchange,提问作者Roman11222
相关产品推荐
相关产品推荐

