异步函数作为柯里化首个函数调用报错,如何正确实现?
问题原因
- 所有被
async标记的函数,无论内部return什么值,最终都会自动包装成Promise对象返回。 - 你写的
function1是async函数,调用function1('somepath.html')后,得到的不是你return的箭头函数,而是一个处于pending状态的Promise。此时尝试对Promise执行('my message')调用,自然会抛出“不是函数”的错误。 - 而
function2是普通函数,它直接返回一个异步箭头函数,所以调用function2('somepath.html')得到的是可执行的函数,后续调用自然正常。
解决方法
针对异步函数开头的柯里化场景,有几种可行的实现方式:
方式一:在async环境中用await获取返回的函数
因为function1返回的是Promise,需要先等待它resolve得到真正的函数,再进行调用:
async function function1(path) { const fetchedElement = await fetchElement(path); return (msg) => { console.log(msg); }; } // 必须在async函数中执行 async function run() { const fn = await function1('somepath.html'); fn('my message'); } run();
方式二:调整函数结构,让第一个函数同步返回处理逻辑
如果不想依赖外部的async环境,可以把异步逻辑放到返回的函数内部,让第一个函数保持同步:
function function1(path) { // 先同步返回函数,异步逻辑在这个函数内部处理 return async (msg) => { const fetchedElement = await fetchElement(path); console.log(msg); }; } // 此时调用方式和function2一致,返回的是异步函数,可直接调用 function1('somepath.html')('my message');
这种方式和你的function2结构类似,但如果必须在第一个函数中完成异步操作再返回后续函数,就只能用方式一或方式三。
方式三:用Promise的then方法链式调用
如果不想用async/await,也可以通过then获取resolve后的函数:
async function function1(path) { const fetchedElement = await fetchElement(path); return (msg) => { console.log(msg); }; } function1('somepath.html').then(fn => { fn('my message'); });
内容的提问来源于stack exchange,提问作者Kleber Germano
相关产品推荐
相关产品推荐

