逻辑层 API(wad.logic.*)
逻辑层脚本写在:
html
<script type="text/wad-logic">
// 这里运行在小程序的 appservice V8 上下文
// 有 wx,没有 DOM
</script>注入位置是业务上下文(WxaSub-*),不是 MainContext。所以你能拿到真实的 wx、getApp() 和页面栈。
逻辑层的 wad 是同步的
logic.call、logic.eval、storage.*、net.records 在逻辑层都直接返回结果,不是 Promise。只有 http.* 是 Promise(底层走 wx.request)。
wad.register(name, fn) — 定义 Skill
把插件能力暴露成可调用技能,面板、渲染层、宿主都能调:
js
wad.register('add', function (a, b) {
return a + b; // 返回值必须 JSON 可序列化
});
wad.register('queryOrder', function (orderId) {
return wx.getStorageSync('order_' + orderId) || null;
});约定:
- 返回值必须是对象 / 数组 / 字符串 / 数字 / 布尔;
- 返回
Promise会被当成null,异步结果请用wad.emit推回; - 未注册的函数名、或函数内抛异常,都会以
Error返回,e.code为HOST_ERROR,e.message保留原始描述; - 6 秒没有响应为
TIMEOUT,帧过大为SEND_FAILED。
异步不要用返回值
register 是同步协议。异步能力请先返回一个受理标记,再用事件把结果推回。
js
wad.register('location.now', function () {
wx.getLocation({
success: function (res) { wad.emit('location.now:done', res); },
fail: function (e) { wad.emit('location.now:done', { error: e.errMsg }); }
});
return 'accepted';
});wad.logic.call(fn, ...args)
跨层调用逻辑层 Skill:
- 逻辑层内部:同步直调,直接拿到返回值;
- 面板 / 渲染层:走总线,返回 Promise。
js
// 面板
const sum = await wad.logic.call('add', 1, 2); // 3
const page = await wad.logic.call('getCurrentRoute');wad.logic.eval(expr)
在逻辑层执行任意表达式并返回结果,调试利器:
js
const n = await wad.logic.eval('getCurrentPages().length');
const app = await wad.logic.eval('getApp().globalData.theme');| 上下文 | 行为 |
|---|---|
| 面板 / 渲染层 | 走总线,返回 Promise |
| 逻辑层内部 | 同步执行 |
约束
eval 走的是 Runtime.evaluate,不要带 awaitPromise —— 这个 v8_inspector 构建下会导致运行进程崩溃。需要异步结果时,先发起,再轮询或订阅事件。
wad.logic.page()
当前页面的标准化信息:
js
const p = await wad.logic.page();
// { route: 'pages/index/index', options: { id: '42' }, index: 0, appid: 'wx123' }逻辑层里还有一个同步版 wad.page(),返回 { route, options }。
wad.logic.emit(name, data)
渲染层 → 逻辑层的快捷事件,等价于 wad.emit:
js
// 渲染层
wad.logic.emit('dom-ready', { title: document.title });
// 逻辑层
wad.on('dom-ready', function (data) { wad.log(data.title); });完整示例:路由监控
html
<script type="text/wad-logic">
wad.on('pageChange', function (p) {
const stack = wx.getStorageSync('__wad_routes__') || [];
stack.push({ route: p.route, at: Date.now() });
wx.setStorageSync('__wad_routes__', stack.slice(-100));
});
wad.register('routes', function () {
return wx.getStorageSync('__wad_routes__') || [];
});
</script>
<script>
wad.ready.then(function () {
wad.logic.call('routes').then(function (list) {
document.body.innerHTML = '<pre>' +
list.map(function (r) { return r.route; }).join('\n') + '</pre>';
});
});
</script>逻辑层的其它能力
wad.appidOf()
js
wad.appidOf(); // 当前小程序 appidwad.http.*
走 wx.request 的 Promise 封装:
js
const r = await wad.http.get('https://api.example.com/v1/me', {
Authorization: 'Bearer ' + token
});
const r2 = await wad.http.request({
url: 'https://api.example.com/v1/order',
method: 'POST',
body: JSON.stringify({ id: 1 }),
headers: { 'content-type': 'application/json' },
timeout: 10000
});
// → { status, headers, body }wad.net.*
js
const list = wad.net.records(); // 同步,最近网络摘要
wad.net.addRule({ // 投递给宿主,返回 true
match: { url: 'contains:/api/vip' },
response: { setBody: '{"vip":true}' }
});
wad.net.removeRule('rule-id');addRule / removeRule 是「投递」语义:立刻返回 true,宿主稍后生效。规则会归属当前插件。
wad.storage.*
同步读写,底层是 wx.setStorageSync,key 自动加 __wad_<id>_ 前缀:
js
wad.storage.set('token', t); // true / false
const v = wad.storage.get('token');
wad.storage.keys(); // 本插件的 key 列表wad.render.eval()
逻辑层调渲染层是投递,立即返回 null,结果不会回来:
js
wad.render.eval("document.title = 'x'");需要结果时,请让渲染层把结果 wad.emit 回来。
wad.asset / loadWasm / loadScript
js
wad.asset('demo.wasm'); // 资源 URL
wad.loadWasm('demo.wasm'); // wx.request 取 arraybuffer → WebAssembly.instantiate
wad.loadScript('helper.js'); // 沙箱可能禁用 eval详见 资源与 WASM。
注意
- Skill 内不要做长耗时循环,会阻塞逻辑层 JS 线程,直接卡住小程序;
- 不要写别的插件的数据;
- 修改
wxAPI 时记得在detach里还原。