迁移
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 事件上报服务
|
||||
*
|
||||
* LandingSDK 由 index.html 异步加载,加载完成前 window.tracker 只是一个排队用的桩函数;
|
||||
* v2 SDK 不再接受桩队列回放出来的泛型调用 track({ event })(会判「非法上报」丢弃),
|
||||
* 所以这里等 SDK 就绪后再走具名方法 landingPageView / landingPageClick。
|
||||
*/
|
||||
import type { EventCode } from './types'
|
||||
|
||||
const SDK_READY_TIMEOUT_MS = 10000
|
||||
const SDK_POLL_MS = 30
|
||||
|
||||
type LandingTracker = ((payload: Record<string, any>) => Promise<unknown>) & {
|
||||
landingPageView?: (properties?: Record<string, any>) => Promise<unknown>
|
||||
landingPageClick?: (properties?: Record<string, any>) => Promise<unknown>
|
||||
}
|
||||
|
||||
// 等到 window.tracker 被 App.vue initTracker 替换成真正的 SDK track(带具名方法)为止。
|
||||
// 注意:SDK 的 track 是 Proxy,访问任意属性(包括 then)都会被当成事件名,所以不能直接把它交给 Promise resolve,
|
||||
// 否则 Promise 会去调它的 then 而永远不落定;这里用对象包一层。
|
||||
function waitForTracker(): Promise<{ tracker: LandingTracker | null }> {
|
||||
return new Promise((resolve) => {
|
||||
const startedAt = Date.now()
|
||||
const check = () => {
|
||||
const tracker = (window as any).tracker as LandingTracker | undefined
|
||||
if (tracker && typeof tracker.landingPageView === 'function') {
|
||||
resolve({ tracker })
|
||||
return
|
||||
}
|
||||
if (Date.now() - startedAt > SDK_READY_TIMEOUT_MS) {
|
||||
resolve({ tracker: null })
|
||||
return
|
||||
}
|
||||
setTimeout(check, SDK_POLL_MS)
|
||||
}
|
||||
check()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件上报服务类
|
||||
*/
|
||||
export class EventTracker {
|
||||
|
||||
/**
|
||||
* 发送事件到服务器
|
||||
*/
|
||||
async sendEvent(eventCode: EventCode, properties?: Record<string, any>) {
|
||||
const { tracker } = await waitForTracker()
|
||||
if (!tracker) {
|
||||
console.log('LandingSDK 未就绪,事件丢弃:' + eventCode)
|
||||
return
|
||||
}
|
||||
try {
|
||||
if (eventCode === 'landing_page_view' && typeof tracker.landingPageView === 'function') {
|
||||
await tracker.landingPageView(properties)
|
||||
} else if (eventCode === 'landing_page_click' && typeof tracker.landingPageClick === 'function') {
|
||||
await tracker.landingPageClick(properties)
|
||||
} else {
|
||||
await tracker({ event: eventCode, ...properties })
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('埋点上报失败:' + eventCode + ' ' + err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 单例实例
|
||||
let trackerInstance: EventTracker | null = null
|
||||
|
||||
/**
|
||||
* 获取事件上报器实例(自动初始化,无需手动初始化)
|
||||
*/
|
||||
export function getEventTracker(): EventTracker {
|
||||
if (!trackerInstance) {
|
||||
trackerInstance = new EventTracker()
|
||||
}
|
||||
return trackerInstance
|
||||
}
|
||||
Reference in New Issue
Block a user