# 如何提供异步配置的接口 回顾一下我们常用的提供拓展接口方式 1. 定义privider 2. 在被拓展的组件中调用`BI.Providers.getProvider().xxx` 3. 开发者通过`BI.config(xxx,privider => provider.inject())`注册 我们提供的配置接口,绝大多数时候都要求BI.config 要在资源加载前执行 但是有些时候,插件资源是异步加载到,配置代码要异步执行,该如何设计接口? ![示例](../images/18.gif) 这里分享一个利用响应式特性开放异步接口的方式,核心思路是将拓展数据定义为响应式的,然后组件层采用响应式写法 首先我们在Provider中定义响应式数据 ```js const Provider = function () { const state = Fix.define({ menus: [], }); this.inject = function (menu) { state.menus.push(menu); }; this.$get = function () { return BI.inherit(BI.OB, { getMenus: () => { return state.menus.slice(0); }, }); }; }; BI.provider("demo.provider.menus", Provider); ``` 之后再组件中通过函数响应式使用provider提供的数据即可 ```js const Menus = function () { const getMenuItems = function () { return BI.Providers.getProvider("demo.provider.menus").getMenus(); }; const defaultMenus = [ { type: "bi.button", text: "第一个", }, { type: "bi.button", text: "第二个", }, ]; return { type: "bi.vertical", items: () => BI.concat(defaultMenus, getMenuItems()), }; }; ``` 开发者依然通过同步的方式调用`BI.config`,但是配置函数却可以是异步的 (思考一下为什么不是`setTimout(() => BI.config()`这种写法) ```js BI.config("demo.provider.menus", provider => { setTimeout(() => { provider.inject({ type: "bi.button", text: "第三个", }); }, 4000); }); ``` 最终的效果呈现 ![示例](../images/19.gif) ```demo const Provider = function () { const state = Fix.define({ menus: [], }); this.inject = function (menu) { state.menus.push(menu); }; this.$get = function () { return BI.inherit(BI.OB, { getMenus: () => { return state.menus.slice(0); }, }); }; }; BI.provider("demo.provider.menus", Provider); const Menus = function () { const getMenuItems = function () { return BI.Providers.getProvider("demo.provider.menus").getMenus(); }; const defaultMenus = [ { type: "bi.button", text: "第一个", }, { type: "bi.button", text: "第二个", }, ]; return { type: "bi.vertical", items: () => BI.concat(defaultMenus, getMenuItems()), }; }; BI.config("demo.provider.menus", provider => { setTimeout(() => { provider.inject({ type: "bi.button", text: "第三个", }); }, 4000); }); const Widget10 = BI.createWidget({ type: "bi.vertical", items: [ { el: Menus(), }, ], }); return Widget10; ```