最近遇到了一个问题, 场景如下. 有一部分功能需要依赖第三方js文件, 由于业务代码是离线化的而第三方js文件却是从网络获取, 其加载时间必定晚于业务代码执行时间. 那么如何在不修改业务代码的情况下, 又保证不会因为加载顺序而出问题呢? 我们可以将每个方法分别包装一层替代原本的方法, 在包装方法中, 如果判断加载完毕可以调用了, 则调用方法, 并将原方法替换会包装方法. 如果未加载完毕, 则延时一段时间, 继续调用包装方法, 形成递归, 直到其加载完毕才产生实际调用.
举个栗子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| window.lib = null; setTimeout(() => { window.lib = { add: function(a, b) { return new Promise(resolve => resolve(a + b)); }, log: function(c) { console.log(c); } }; }, 2000); var actions = { func: function(a, b) { window.lib.add(a, b).then(result => { window.lib.log(result); console.log(result); }); } }; actions.func(2, 3);
|
接下来编写包装方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function wrap(target, funcName) { var origin = target[funcName]; target[funcName] = function(...args) { return new Promise(resolve => { if (window.lib) { resolve(origin.call(target, ...args)); target[funcName] = origin; } else { setTimeout(() => { resolve(target[funcName].call(null, ...args)); }, 100); } }); }; }
|
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| window.lib = null; setTimeout(() => { window.lib = { add: function(a, b) { return new Promise(resolve => resolve(a + b)); }, log: function(c) { console.log(c); } }; }, 2000); var actions = { func: function(a, b) { window.lib.add(a, b).then(result => { window.lib.log(result); console.log(result); }); } }; function wrap(target, funcName) { var origin = target[funcName]; target[funcName] = function(...args) { return new Promise(resolve => { if (window.lib) { resolve(origin.call(target, ...args)); target[funcName] = origin; } else { setTimeout(() => { resolve(target[funcName].call(null, ...args)); }, 100); } }); }; } wrap(actions, "func"); actions.func(2, 3);
|
执行代码, 不会再抛出异常