Vue.js中创建异步构造类并正确获取异步返回数据的方法
问题原因
async 函数返回值永远是Promise对象,而类的构造函数是同步执行的,无法等待内部异步请求执行完成,因此直接在constructor里调用异步接口、再通过new Filters()赋值,永远只能拿到pending状态的Promise,不可能直接获取接口真实返回值。
正确实现方案
不要把异步初始化逻辑写在类的构造函数中,将异步逻辑抽为独立的初始化方法,在Vue生命周期中等待异步执行完成后再赋值。
第一步:改造Filters类
构造函数仅做同步的基础属性初始化,异步拉取数据的逻辑抽为单独的init方法:
class Filters { constructor() { // 仅做同步初始化 this.filterList = []; } async init() { const recordId = window.parent.Xrm.Page.data.entity.getId().replace(/[{}]/g, ""); const query = `?$select=*&$filter=_new_table_value eq ${recordId}&$orderby=ice_name asc`; const result = await window.parent.Xrm.WebApi.retrieveMultipleRecords('ice_filterstable', query); this.filterList = result; return result; } }
第二步:调整Vue组件逻辑
created生命周期支持async写法,等待Filters实例初始化完成、接口数据返回后,再给data中的属性赋值:
export default { data() { return { Filters: [] }; }, async created() { const filtersIns = new Filters(); // 等待异步接口返回后再赋值 this.Filters = await filtersIns.init(); } };
可选:需要复用Filters类实例方法的写法
如果后续需要调用Filters实例上的其他方法,可以直接把实例存在data中,等init完成后再使用:
export default { data() { return { filtersInstance: null }; }, async created() { const instance = new Filters(); await instance.init(); // 初始化完成后再赋值实例,此时实例上的filterList已经是接口返回的真实数据 this.filtersInstance = instance; // 业务中取筛选数据可通过 this.filtersInstance.filterList 获取 } };
注意事项
- JS构造函数本身是同步设计,没有任何hack方式能让构造函数直接返回异步结果,所有类中的异步初始化逻辑都应该抽为显式的初始化方法调用
- 异步赋值过程中可以按需增加loading状态,避免页面渲染空数据报错

内容的提问来源于stack exchange,提问作者MVC_Nhibernate
相关产品推荐
相关产品推荐

