基于前置响应的React/JS/TS批量API调用问题咨询
问题解答
一、如何返回不同接口的状态结果
当前代码的问题是一旦某个步骤出错就直接返回统一错误响应,无法区分createProjectPeopleOrganization成功但createProjectPeople失败的场景。解决方案是收集每一条数据的处理明细,不管成功还是失败,最后返回汇总结果,让用户能清晰看到每一项的各步骤状态:
- 初始化结果数组,存储每条
peopleAndOrganizationIds项的处理状态 - 对单条数据的处理逻辑单独做try-catch,捕获该条内各步骤的错误
- 记录每个步骤的状态(成功/失败)、返回数据或错误信息
- 最终返回包含所有处理明细的响应,而非中途中断
修改后的核心逻辑示例:
export const bulkSave = async ({ data }) => { const { projectId, peopleAndOrganizationIds } = data; const results = []; for (const item of peopleAndOrganizationIds) { const { personId, organizationId } = item; const result = { personId, organizationId, getPerson: { status: 'pending' }, createProjectPeopleOrganization: { status: 'pending' }, createProjectPeople: { status: 'pending' } }; try { // 获取Person信息 const { person } = await getPerson({ personId }); if (!person) { result.getPerson = { status: 'failed', error: 'No person found' }; results.push(result); continue; } result.getPerson = { status: 'success', data: person }; // 创建组织关联 const { created_project_people_organization } = await createProjectPeopleOrganization({ object: { project_id: projectId, global_directory_organization_id: organizationId, context: person.organization, }, }); result.createProjectPeopleOrganization = { status: 'success', data: created_project_people_organization }; // 创建人员关联 const { created_project_people } = await createProjectPeople({ object: { project_id: projectId, global_directory_people_id: personId, project_people_organization_id: created_project_people_organization?.id, }, }); result.createProjectPeople = { status: 'success', data: created_project_people }; } catch (error) { // 根据错误发生阶段标记对应步骤的失败状态 if (result.createProjectPeopleOrganization.status === 'success') { result.createProjectPeople = { status: 'failed', error: error.message || 'Failed to create project people' }; } else if (result.getPerson.status === 'success') { result.createProjectPeopleOrganization = { status: 'failed', error: error.message || 'Failed to create project people organization' }; } else { result.getPerson = { status: 'failed', error: error.message || 'Failed to get person' }; } } finally { results.push(result); } } // 返回汇总结果,用200状态码让前端通过明细判断各条状态 return new Response(JSON.stringify(results), { status: 200, headers: { 'Content-Type': 'application/json' }, statusText: 'Bulk operation completed with details' }); };
返回的响应体中,每条数据的三个步骤状态清晰可见,用户能明确区分哪条数据出现了“组织关联成功但人员关联失败”的情况。
二、for of循环是否合适
是否合适取决于业务需求:
- 如果要求串行处理:比如接口有并发调用限制、或者必须按顺序处理每条数据(前一条完成后再处理下一条),
for of+await完全合适,它能保证处理顺序,且前一条的异步操作完成后才会执行下一条。 - 如果允许并行处理:若每条数据的处理相互独立(无依赖关系),可以改用
Promise.allSettled并行处理,提升批量操作效率。但要注意:并行调用可能触发接口限流,需确认后端API的并发限制。
并行处理简化示例:
// 抽离单条数据处理逻辑 const processItem = async (item, projectId) => { const { personId, organizationId } = item; const result = { personId, organizationId, getPerson: { status: 'pending' }, createProjectPeopleOrganization: { status: 'pending' }, createProjectPeople: { status: 'pending' } }; // 此处复用单条数据的处理逻辑(同上面循环内的代码) return result; }; // 并行处理所有数据 const results = await Promise.allSettled( peopleAndOrganizationIds.map(item => processItem(item, projectId)) ); // 格式化results后返回响应
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

