如何避免需等待加载的对象中出现重复代码?解决加载事件绑定问题
优化异步对象就绪回调的通用方案
这个场景我简直太熟悉了——很多自定义异步对象都会踩这个“绑定事件时目标已经就绪”的坑,每次都写if(!ob.loaded)不仅冗余,还容易漏写或者写错判断逻辑。咱们可以通过封装通用处理逻辑的方式彻底解决这个问题,下面给你几个实用的方案:
方案1:给原对象原型扩展就绪方法
如果SomeAjaxObject是你可控的代码(或者允许扩展原型),直接给它加一个whenReady方法,把判断和事件绑定的逻辑封装进去:
// 扩展SomeAjaxObject的原型方法 SomeAjaxObject.prototype.whenReady = function(callback) { // 先判断是否已就绪 if (this.loaded) { // 直接执行回调,用call确保this指向当前实例 callback.call(this, this); } else { // 未就绪则绑定load事件,触发时执行回调 this.on('load', () => { callback.call(this, this); }); } };
之后使用时就非常简洁,再也不用重复写判断:
const ob = new SomeAjaxObject(); ob.whenReady((instance) => { doSomeThing(instance); });
方案2:独立工具函数(不修改原对象)
如果SomeAjaxObject是第三方库,没法修改它的原型,就写一个独立的工具函数来封装逻辑:
// 通用工具函数:处理Ajax对象就绪回调 function whenAjaxReady(ajaxObj, callback) { if (ajaxObj.loaded) { callback(ajaxObj); } else { ajaxObj.on('load', () => { callback(ajaxObj); }); } }
使用方式同样简单:
const ob = new SomeAjaxObject(); whenAjaxReady(ob, (instance) => { doSomeThing(instance); });
方案3:Promise化适配现代异步代码
如果你的项目已经在使用Promise/async-await,还可以把这个逻辑Promise化,让它更好地融入现代异步代码风格:
// 返回Promise的就绪处理函数 function ajaxReadyPromise(ajaxObj) { return new Promise((resolve) => { if (ajaxObj.loaded) { resolve(ajaxObj); } else { ajaxObj.on('load', () => { resolve(ajaxObj); }); } }); }
使用时可以用async-await让代码更像同步逻辑:
async function handleAjaxTask() { const ob = new SomeAjaxObject(); const readyInstance = await ajaxReadyPromise(ob); doSomeThing(readyInstance); }
或者用.then()链式调用:
const ob = new SomeAjaxObject(); ajaxReadyPromise(ob).then((readyInstance) => { doSomeThing(readyInstance); });
这些方案的核心都是把重复的判断+事件绑定逻辑抽离成通用代码,以后不管多少地方需要处理这个场景,只需要调用封装好的方法/函数就行,既减少了冗余,也降低了出错的概率。
内容的提问来源于stack exchange,提问作者Mojimi
相关产品推荐
相关产品推荐

