同步正常的CustomFunctions改用异步后启动时报Unexpected message type错误
我之前也碰到过一模一样的问题,这个错误本质是Office加载项和Excel宿主之间的通信格式不匹配导致的——而且它居然在你的代码执行前就触发,说明大概率是异步函数的配置或者声明环节出了问题。下面给你几个针对性的排查和解决步骤:
1. 先检查异步函数的声明与配置是否合规
异步自定义函数必须同时满足代码层面和配置文件层面的要求,缺一个都可能触发这个错误:
- 代码里的函数必须是
async函数,或者明确返回Promise类型,还要加上正确的JSDoc注释:
/** * 异步获取数据的自定义函数 * @customfunction * @param {number} delay 延迟时间(毫秒) * @returns {Promise<string>} 返回异步加载的结果 */ async function asyncGetData(delay) { return new Promise((resolve) => { setTimeout(() => { resolve("异步数据加载完成"); }, delay); }); }
- 对应的
function.json里,必须把这个函数的isAsync设为true:
{ "name": "asyncGetData", "description": "异步获取数据的自定义函数", "parameters": [ { "name": "delay", "description": "延迟时间(毫秒)" } ], "isAsync": true, "returns": "string" }
要是function.json里漏了这个标记或者标记错误,Excel宿主会把它当成同步函数处理,直接触发消息类型不匹配的错误。
2. 试试切换到稳定版Office.js
你现在用的是beta版的excel-win32-16.01.js,beta版本偶尔会有兼容性问题。建议先换成稳定版的Office.js测试:
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
如果稳定版能正常运行,那基本就是beta版的bug了,可以考虑给Office团队反馈,或者等beta版更新后再用。
3. 检查异步函数的返回值逻辑
确保你的异步函数不会不小心返回非Promise类型的值——比如有时候写代码时手滑,直接return了普通字符串而不是Promise。另外,虽然你的错误是代码执行前触发的,但Promise链里的未捕获异常也可能间接干扰通信层,所以尽量给Promise加上catch处理。
4. 验证加载项清单文件的配置
如果是侧加载的加载项,检查manifest.xml里的自定义函数配置是否正确。比如要确保<ExtensionPoint xsi:type="CustomFunctions">节点指向了正确的JS文件和function.json路径,权限配置也没出错。
5. 更新Excel到最新版本试试
这个错误出现在excel-win32-16.01.js对应的Excel桌面版,可能是特定版本的宿主bug。试试把Excel更到最新版,或者去Excel Online上测试你的异步函数,如果在线版没问题,那就是桌面版的版本问题了。
额外提一句:你说错误的消息类型是1002,结合触发时机来看,这是Excel在解析自定义函数的元数据(从JSDoc或者
function.json)时就发现了格式错误,所以优先检查上面前两点的配置,大概率能解决问题。
内容的提问来源于stack exchange,提问作者Nicky

