目录
我们发现,小程序里面大部分API都是异步接口,这根它的双线程模型有很大关系。
以下举一个标准的异步接口showToast
。
Call&Callback
在logic层,我们调用了 showToast
方法:
xx.showToast({
title: 'Hello world'
})
实际上这接口发到 master 层去处理的:
function showToast (options) {
postMessage({
cmd: API_CALL,
apiName: 'showToast',
apiParams: options
})
}
考虑到我们的接口都是异步回调,在 master 层处理完毕后需要通知回 logic 层:
postMessageToLogic(
{
cmd: API_CALLBACK,
data,
error: null,
msgId: res.msgId
},
0,
0
)
上面我们看到了一个 msgId,这是各层间传递信息标识的唯一id,而 logic 层还需要处理回调结果,我们完善一下:
const msgCallbackFns = {}
function showToast(options) {
msgCallbackFns[msgId] = {
success: isFunction(options.success) ? options.success : noop.bind(options),
fail: isFunction(options.fail) ? options.fail : noop.bind(options),
complete: isFunction(options.complete)
? options.complete
: noop.bind(options),
};
postMessage({
cmd: API_CALL,
apiName: "showToast",
apiParams: options,
})
}
在API调用的时候,把自身的回调函数缓存起来,等收到回调的信息时,执行相应的回调,再把缓存删掉。
...
case API_CALLBACK: {
// api回调
const apiCallbackFns = msgCallbackFns[res.msgId]
if (apiCallbackFns) {
if (res.error) {
apiCallbackFns.fail(res.error)
} else {
apiCallbackFns.success(res.data)
}
apiCallbackFns.complete()
delete msgCallbackFns[res.msgId]
}
break
}
Sync
在一些接口上,也能提供同步的接口,比如:getStorageSync
。
这个比较好理解,因为 localStorage 无论在父级页面或者iframe中都能取到,而且本身也是一个同步方法,所以可以在 master 层和 logic 层都实现一遍。
我们还发现,小程序的 setStorage
比 web 上的 localStorage 似乎可以写入的格式多一些,还支持Date格式类型,方法是通过写入JSON来实现,参照 LocalStorage