优化重试请求逻辑

This commit is contained in:
tangly1024
2022-04-29 14:50:54 +08:00
parent 869cd0a3c9
commit 245290d46d
4 changed files with 60 additions and 33 deletions

View File

@@ -3,7 +3,7 @@ import { getDataFromCache, setDataToCache } from '@/lib/cache/cache_manager'
import { getPostBlocks } from '@/lib/notion/getPostBlocks'
import { idToUuid } from 'notion-utils'
import { defaultMapImageUrl } from 'react-notion-x'
import { isIterable } from '../utils'
import { deepClone, isIterable } from '../utils'
import getAllPageIds from './getAllPageIds'
import { getAllPosts } from './getAllPosts'
import { getAllTags } from './getAllTags'
@@ -25,7 +25,9 @@ export async function getGlobalNotionData({
from,
pageType = ['Post']
}) {
const notionPageData = await getNotionPageData({ pageId, from })
// 深拷贝数据
const notionPageData = deepClone(await getNotionPageData({ pageId, from }))
const allPosts = await getAllPosts({ notionPageData, from, pageType })
notionPageData.allPosts = allPosts
// 删除前端不需要的数据
@@ -196,8 +198,9 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
if (!pageRecordMap) {
return []
}
pageId = idToUuid(pageId)
const block = pageRecordMap.block
const rawMetadata = block[pageId].value
const rawMetadata = block[pageId]?.value
// Check Type Page-Database和Inline-Database
if (
rawMetadata?.type !== 'collection_view_page' &&
@@ -207,7 +210,6 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
return null
}
pageId = idToUuid(pageId)
const collection = Object.values(pageRecordMap.collection)[0]?.value
const collectionQuery = pageRecordMap.collection_query
const schema = collection?.schema

View File

@@ -1,28 +1,19 @@
import BLOG from '@/blog.config'
import { NotionAPI } from 'notion-client'
import { getDataFromCache, setDataToCache } from '@/lib/cache/cache_manager'
import { deepClone, delay } from '../utils'
export async function getPostBlocks(id, from, slice, retryCount = 3) {
export async function getPostBlocks(id, from, slice) {
const cacheKey = 'page_block_' + id
let pageBlock = await getDataFromCache(cacheKey)
if (pageBlock) {
console.log('[请求缓存]:', `from:${from}`, `id:${id}`, cacheKey)
console.log('[请求缓存]:', `from:${from}`, cacheKey)
return filterPostBlocks(id, pageBlock, slice)
}
const authToken = BLOG.NOTION_ACCESS_TOKEN || null
const api = new NotionAPI({ authToken })
try {
console.warn('[请求API]:', `from:${from}`, `id:${id}`)
pageBlock = await api.getPage(id)
console.warn('[请求成功]', `from:${from}`, `id:${id}`)
} catch (error) {
console.error('[请求失败]', `from:${from}`, `id:${id}`, `error:${error}`)
if (retryCount && retryCount > 0) { // 重试
console.error('[重试请求]', `from:${from}`, `id:${id}`, `剩余次数:${retryCount}`)
return getPostBlocks(id, from, slice, retryCount - 1)
}
return null
}
console.warn('[请求API]:', `from:${from}`, `id:${id}`)
pageBlock = await getPageWithRetry(id, from)
console.warn('[请求完成]: 结果', `${pageBlock ? '成功' : '失败'}`, `from:${from}`, `id:${id}`)
if (pageBlock) {
await setDataToCache(cacheKey, pageBlock)
@@ -31,6 +22,33 @@ export async function getPostBlocks(id, from, slice, retryCount = 3) {
return pageBlock
}
/**
* 调用接口,失败会重试
* @param {*} id
* @param {*} retryAttempts
*/
async function getPageWithRetry(id, from, retryAttempts = 3) {
if (retryAttempts && retryAttempts > 0) {
console.error('[重试请求]', `from:${from}`, `id:${id}`, `剩余次数:${retryAttempts}`)
try {
const authToken = BLOG.NOTION_ACCESS_TOKEN || null
const api = new NotionAPI({ authToken })
return await api.getPage(id)
} catch (e) {
await delay(1000)
const cacheKey = 'page_block_' + id
const pageBlock = await getDataFromCache(cacheKey)
if (pageBlock) {
console.error('[获取缓存]', `from:${from}`, `id:${id}`, `剩余次数:${retryAttempts}`)
return pageBlock
}
return await getPageWithRetry(id, from, retryAttempts - 1)
}
} else {
return null
}
}
/**
* 获取到的blockMap删除不需要的字段
* @param {*} id 页面ID
@@ -74,15 +92,3 @@ function filterPostBlocks(id, pageBlock, slice) {
}
return clonePageBlock
}
function deepClone(obj) {
const newObj = Array.isArray(obj) ? [] : {}
if (obj && typeof obj === 'object') {
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
newObj[key] = (obj && typeof obj[key] === 'object') ? deepClone(obj[key]) : obj[key]
}
}
}
return newObj
}

View File

@@ -80,3 +80,22 @@ export function isObject(item) {
export function isIterable(obj) {
return obj != null && typeof obj[Symbol.iterator] === 'function'
}
export function deepClone(obj) {
const newObj = Array.isArray(obj) ? [] : {}
if (obj && typeof obj === 'object') {
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
newObj[key] = (obj && typeof obj[key] === 'object') ? deepClone(obj[key]) : obj[key]
}
}
}
return newObj
}
/**
* 延时
* @param {*} ms
* @returns
*/
export const delay = ms => new Promise(resolve => setTimeout(resolve, ms))

View File

@@ -29,7 +29,7 @@ const Slug = props => {
})
}
}
}, 5000)
}, 10000)
const meta = { title: `${props?.siteInfo?.title || BLOG.TITLE} | loading` }
return <ThemeComponents.LayoutSlug {...props} showArticleInfo={true} meta={meta} />
}