02_uni_api初始化以及promise化过程
一.uni_api初始化过程
function initUni(platform = wx) {
const wrapper = initWrapper(protocols2);
return new Proxy({}, {
get(target, key) {
if (hasOwn$1(shims, key)) {
return promisify(key, shims[key])
}
if (hasOwn$1(baseApis, key)) {
return promisify(key, baseApis[key])
}
if(hasOwn$1(protocols, key)) {
return promisify(key, wrapper(key, platform[key]))
}
return promisify(key, platform[key])
}
})
}
exports.uni = initUni(wx)
-
可以看到,uni api的初始化过程中,会将不同平台的api经过Proxy包装,实现api调用的拦截,有关Proxy的使用,可以看这篇文章:
-
shims api的调用
uni.createSelectorQuery() <==> promisify(“createSelectorQuery”, shims[“createSelectorQuery”])()
-
baseApis api的调用
uni.$on(“eventName”, (datas) => {}) <==> promisify(“$on”, baseApis[“$on”])(“eventName”, (datas) => {})
-
protocols api的调用
const wrapper = initWrapper(protocols);
uni.getSystemInfo() <==> promisify(“getSystemInfo”, wrapper(“getSystemInfo”, platform[“getSystemInfo”]))()
-
platform api的调用
uni.setStorage({key: “token”, data: “123”}) <==> promisify(“setStorage”, platform[“setStorage”])({key: “token”, data: “123”})
baseApis中的api属于uni-app特有的api,当我们通过uni.xxx调用baseApis中的api时,实际是调用uni-app特有的api。
然而,当我们通过uni.xxx调用uni api时,如果是baseApis之外的api,最终都会调用到不同平台的api,例如在微信小程序环境下,调用uni.getSystemInfo(),最终会调用wx.getSystemInfo()。
二.uni api的promise化过程
当我们通过uni.xxx调用uni api时,都会先调用promisify将实际需要调用的api接口进行预处理,在进行预处理时首先会根据调用的api名称判断,是否可以promise化,如果不可以promise化,则直接返回实际调用api,如果可以promise化,则处理成支持返回Promise的api,也就是将uni api promise化。
function promisify(name, api) {
if (!shouldPromise(name)) {
return api;
}
if (!isFunction(api)) {
return api;
}
return function promiseApi(options = {}, ...rest) {
if (isFunction(options.success) || isFunction(options.fail) || isFunction(options.complete)) {
return wrapperReturnValue(name, invokeApi(name, api, options, rest));
}
return wrapperReturnValue(name, handlePromise(new Promise((resolve2, reject) => {
invokeApi(name, api, extend({}, options, {
success: resolve2,
fail: reject
}), rest);
})));
}
}
不能promise化的api:
- 以create开头的api
- 以Manager结尾的api
- 以$开头的api
- getLocale、setLocale、sendNativeEvent、restoreGlobal、requireGlobal、getCurrentSubNVue、getMenuButtonBoundingClientRect、interceptors、getSubNVueById、requireNativePlugin、upx2px、hideKeyboard、canIUse、base64ToArrayBuffer、arrayBufferToBase64、getDeviceInfo、getAppBaseInfo、getWindowInfo、getSystemSetting、getAppAuthorizeSetting
- 以report开头的api
- 以Interceptor结尾的api
- 以Sync结尾的api
- 以on开头的api
- 以off开头的api
function invokeApi(method, api, options, params) {
const interceptor = getApiInterceptorHooks(method);
if (interceptor && Object.keys(interceptor).length) {
if (isArray(interceptor.invoke)) {
const res = queue$1(interceptor.invoke, options);
return res.then((options2) => {
return api(wrapperOptions(interceptor, options2), ...params);
});
} else {
return api(wrapperOptions(interceptor, options), ...params);
}
}
return api(options, ...params);
}
uni api的promise化过程:
当我们通过uni.xxx调用uni api时,最后都会调用invokeApi和wrapperReturnValue