一开始加载用户信息存储在sdk里,但是初次加载时,sdk尚未加载完毕,无法获取用户信息等
//umi 框架里 getInitialState只会在初始化时执行,无论此时sdk是否加载完成,
//如果sdk没有加载完成则无法获取用户信息,所以要确保sdk完成加载,并获取到相应的用户信息才能退出这个函数
export async function getInitialState(): Promise<{
settings?: Partial<LayoutSettings>;
currentUser?: Record<string, any>;
fetchUserInfo?: () => Promise<Record<string, any> | undefined>;
}> {
let currentUser: Record<string, any> | undefined = await fetchUserInfo();
return {
fetchUserInfo,
currentUser,
settings: {},
};
}
可以通过定时器+promise来实现,直到sdk加载完毕后进行相关操作,未加载完毕则通过定时器返反复获取sdk的加载情况,才把用户信息resolve出去。 如果不用promise的resolve,单纯使用定时器无法实现该功能,因为定时器无论结果如何,都会接着执行下面的代码,只是隔了一段时间后接着执行定时器里的内容而已。在定时器第一次执行,sdk尚未加载完成,拿不到用户信息,此时fetchUserInfo()已经返回undefined,则getInitialState()已经拿到用户信息为undefined,无论后续定时器再执行拿到结果,getInitialState()的值已经不再变化
const fetchUserInfo = (): Promise<Record<string, any> | undefined> => {
const getUserInfo = async () => {
if (!window?.jsapi) {
return undefined;
} else {
let info = await window?.jsapi?.login.getUserInfo();
// 没有登录则没有用户信息
if (!info) return {};
// 登录的用户信息
const { userId } = info;
let User;
try {
// 获取该用户邮箱是否为渠道邮箱
User = await getUserEmailAuthentication(userId);
} catch (error) {
User = { success: false} ;
}
if (!User?.success) {
message.error('User email has no corresponding channel account.');
}
const userInfo = {
...info,
...User?.data,
UserEmailAuthentication: User?.success,
};
return userInfo;
}
};
return new Promise((resolve) => {
let userInfo;
const intervalId = setInterval(() => {
userInfo = getUserInfo();
if (userInfo) {
clearInterval(intervalId);
resolve(userInfo);
}
}, 1000);
});
};
总结: 通过script标签引入外部js时,确保js已经加载完毕后,再调用相关的功能