飞书文档转Markdown工具feishu2md中的知识空间节点列表获取优化
【免费下载链接】feishu2md 一键命令下载飞书文档为 Markdown 项目地址: https://gitcode.com/gh_mirrors/fe/feishu2md
在开源项目feishu2md的开发过程中,我们发现了一个关于获取知识空间子节点列表的重要性能问题。这个问题会导致程序在特定情况下陷入死循环,严重影响工具的使用体验。
问题背景
feishu2md是一个将飞书文档转换为Markdown格式的工具,其中需要处理知识空间中的文档结构。在获取知识空间子节点列表时,原始实现存在一个关键缺陷:没有正确处理分页查询的逻辑。
技术分析
在飞书API的设计中,GetWikiNodeList接口采用了分页机制返回结果。当子节点数量较多时,API会返回部分结果并附带一个page_token用于获取下一页数据。原始实现中虽然考虑了分页逻辑,但存在两个主要问题:
- 首次查询时没有显式设置
page_token为nil - 后续分页查询时没有正确传递上一次查询返回的
page_token
这导致API总是返回第一页结果,程序误以为还有更多数据需要获取,从而陷入无限循环。
解决方案
我们通过以下修改解决了这个问题:
func (c *Client) GetWikiNodeList(ctx context.Context, spaceID string, parentNodeToken *string) ([]*lark.GetWikiNodeListRespItem, error) {
// 首次查询明确设置page_token为nil
resp, _, err := c.larkClient.Drive.GetWikiNodeList(ctx, &lark.GetWikiNodeListReq{
SpaceID: spaceID,
PageSize: nil,
PageToken: nil,
ParentNodeToken: parentNodeToken,
})
if err != nil {
return nil, err
}
flag := resp.HasMore
nodes := resp.Items
// 正确处理分页查询
for flag {
resp, _, err := c.larkClient.Drive.GetWikiNodeList(ctx, &lark.GetWikiNodeListReq{
SpaceID: spaceID,
PageSize: nil,
PageToken: &resp.PageToken, // 传递正确的page_token
ParentNodeToken: parentNodeToken,
})
if err != nil {
return nil, err
}
nodes = append(nodes, resp.Items...)
flag = resp.HasMore
}
return nodes, nil
}
改进要点
- 明确初始化参数:首次查询时显式设置
page_token为nil,避免歧义 - 正确处理分页:在后续查询中正确使用API返回的
page_token获取下一页数据 - 完整收集结果:将所有分页结果合并后返回,对外提供完整的节点列表
影响范围
这一改进主要影响以下场景:
- 处理包含大量子节点的知识空间时
- 导出复杂文档结构时
- 批量处理多个知识空间时
最佳实践
在使用分页API时,开发者应当:
- 仔细阅读API文档,理解分页机制
- 正确处理首次查询和后续查询的参数差异
- 实现完整的循环获取逻辑
- 设置合理的终止条件
这个修复不仅解决了死循环问题,还提高了工具在处理大型知识空间时的稳定性和可靠性。对于需要处理飞书文档结构的开发者来说,理解这种分页机制的正确实现方式非常重要。
【免费下载链接】feishu2md 一键命令下载飞书文档为 Markdown 项目地址: https://gitcode.com/gh_mirrors/fe/feishu2md
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



