You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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变量存在作用域问题。按以下步骤修改:

  1. 将回调式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);
                }
            });
        });
    };
    
  2. 修改主函数,等待所有上传完成
    使用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");
        }
    };
    
  3. 完善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;
    };
    
  4. 简化回调处理函数
    已使用await语法,可简化函数逻辑:

    const handleAttachmentsCallback = async (result) => {
        return uploadFile(result.value.content);
    };
    

关键说明

  • 用Promise包装Office回调API是插件异步开发的标准方式,能更好地与async/await配合
  • Promise.all确保所有异步操作完成后再执行后续逻辑,避免提前跳转
  • 完善fetch的错误处理,避免将HTTP错误误判为上传成功

内容的提问来源于stack exchange,提问作者Kamerov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 12:17:24