OpenUI5中Promise resolve未触发问题排查求助
问题排查与修复方案
核心原因
当不传callback时await一直挂起的根本问题是:dataReceived事件从未被触发,导致Promise始终处于pending状态,await自然无法返回。
OpenUI5的dataReceived事件仅在「数据首次加载完成」或「刷新后数据到达」时触发。如果你的Binding对象在调用attachOnceAsync之前,数据已经加载完成,后续绑定的事件监听不会被执行,resolve也就不会被调用,await会一直处于等待状态。
代码问题分析
你的封装逻辑只处理了「事件触发时执行回调并resolve」的常规场景,但完全忽略了「数据已经加载完成、事件不会再触发」的边界情况。另外,resolve(oEvent, ...args)写法无效——Promise的resolve仅接受一个参数,多余参数会被直接忽略,但这不是导致await挂起的直接原因。
修复代码
修改attachOnceAsync,在绑定事件前先检查Binding的状态,若数据已加载则直接resolve,否则再等待事件触发:
attachOnceAsync: function(binding, callback) { var args = [...arguments]; args.splice(0, 2); return new Promise((resolve, reject) => { // 抽离resolve逻辑为复用函数 const handleResolve = (oEvent) => { if (typeof callback === 'function') { // 更可靠的AsyncFunction判断方式 const isAsync = callback instanceof (async function(){}).constructor; if (isAsync) { callback(oEvent, ...args) .then(() => resolve(oEvent)) .catch(reject); } else { try { callback(oEvent, ...args); resolve(oEvent); } catch (err) { reject(err); } } } else { resolve(oEvent); // 仅传递第一个参数,多余参数无意义 } }; // 检查数据是否已加载完成(以ODataBinding为例,其他Binding类型需调整判断逻辑) if (!binding.isInitial()) { // 数据已加载,构造模拟事件对象(或直接传null,根据业务需求调整) const mockEvent = { getSource: () => binding, // 可根据需要补充其他事件属性 }; handleResolve(mockEvent); } else { // 数据未加载,绑定事件等待触发 binding.attachEventOnce("dataReceived", handleResolve); } }); }
额外注意事项
- 不同Binding类型的加载状态判断逻辑不同:
- ODataBinding用
isInitial()(返回false表示数据已加载) - JSONBinding可通过
binding.getData()是否存在有效数据来判断
- ODataBinding用
- 原代码中
callback.constructor.name === "AsyncFunction"的判断方式在部分环境下可能失效,改用instanceof判断更可靠。
内容的提问来源于stack exchange,提问作者GreysonTyrus
相关产品推荐
相关产品推荐

