Outlook插件中getAttachmentContentAsync无法等待API响应问题
解决Outlook插件附件上传时无法等待API响应的问题
我正在使用ReactJS开发Outlook插件,实现附件上传功能,但无法让代码等待服务器的API响应,后续JS代码会立即执行,这会导致上传失败时无法正确处理。
现有代码
主上传函数
const uploadOutlookFile = async (files) => { const options = { asyncContext: { currentItem: item } }; const item = Office.context.mailbox.item; files.map((id) => { // files have attachment id item.getAttachmentContentAsync(id, options, (result) => { const success = handleAttachmentsCallback(result); }); }); if(success) { navigate("/uploadSuccess"); } else { navigate("/uploadFailure"); } };
回调处理函数
const handleAttachmentsCallback = async (result) => { return await uploadFile(result.value.content); };
API上传函数
const uploadFile = async (file) => { let url = `/my/rest/url`; return fetch(url, { method: "POST", body: file.toString(), }); };
遇到的错误
尝试在getAttachmentContentAsync()内添加await时,出现解析错误:
Parsing error: 'await' is only allowed within async functions and at the top levels of modules.
修复方案
核心问题是Office的getAttachmentContentAsync是基于回调的异步API,无法直接用await,同时原代码未正确等待所有异步操作完成,且success变量存在作用域问题。按以下步骤修改:
将回调式API包装为Promise
先编写工具函数,把getAttachmentContentAsync转换为Promise形式,适配async/await语法:const getAttachmentContent = (item, attachmentId) => { return new Promise((resolve, reject) => { item.getAttachmentContentAsync(attachmentId, (result) => { if (result.status === Office.AsyncResultStatus.Succeeded) { resolve(result); } else { reject(result.error); } }); }); };修改主函数,等待所有上传完成
使用Promise.all等待所有附件的获取与上传操作完成,统一处理结果后再执行页面跳转:const uploadOutlookFile = async (files) => { const item = Office.context.mailbox.item; try { // 并行处理所有附件的获取和上传 const uploadResults = await Promise.all( files.map(async (id) => { const result = await getAttachmentContent(item, id); return handleAttachmentsCallback(result); }) ); // 校验所有上传是否成功 const allSuccess = uploadResults.every(res => res.ok); allSuccess ? navigate("/uploadSuccess") : navigate("/uploadFailure"); } catch (error) { // 捕获获取附件或上传失败的异常 navigate("/uploadFailure"); } };完善API上传函数的错误处理
fetch不会在HTTP错误状态码时自动抛出异常,需手动判断响应状态:const uploadFile = async (file) => { let url = `/my/rest/url`; const response = await fetch(url, { method: "POST", body: file.toString(), }); // 仅当响应状态码在200-299区间时视为成功 if (!response.ok) { throw new Error(`上传失败,状态码:${response.status}`); } return response; };简化回调处理函数
已使用await语法,可简化函数逻辑:const handleAttachmentsCallback = async (result) => { return uploadFile(result.value.content); };
关键说明
- 用Promise包装Office回调API是插件异步开发的标准方式,能更好地与
async/await配合 Promise.all确保所有异步操作完成后再执行后续逻辑,避免提前跳转- 完善
fetch的错误处理,避免将HTTP错误误判为上传成功
内容的提问来源于stack exchange,提问作者Kamerov
相关产品推荐
相关产品推荐

